取消WIN32线程池中的预定工作/ io /计时器项

时间:2010-11-18 22:44:57

标签: c++ c windows multithreading threadpool

我一直在玩Windows(新的?)线程池API。我一直在关注Using the Thread Pool Functions中的示例,我一直在仔细研究MSDN上的API。关于清理小组,我有些不了解。

调用SetThreadpoolCallbackCleanupGroup()时,第三个参数描述为

  

如果在释放关联对象之前取消清理组,则调用清理回调。调用CloseThreadpoolCleanupGroupMembers()时会调用该函数。

如果我的理解是正确的,那意味着您可以取消待处理的work / io / timer项并要求它在每个对象上调用清理回调函数而不是原始队列工作/ io / timer项目的回调。这听起来很酷,我想用它。

不幸的是,MSDN上没有记录用于回调的PTP_CLEANUP_GROUP_CANCEL_CALLBACK类型,并且相关示例不使用此功能。

将法律掌握在自己手中,我已将该定义追溯到WinNT.h并找到以下内容。

typedef VOID (NTAPI *PTP_CLEANUP_GROUP_CANCEL_CALLBACK)(
    __inout_opt PVOID ObjectContext,
    __inout_opt PVOID CleanupContext
    );

删除这个有趣的宣言上的残骸让你:

typedef void ( __stdcall * PTP_CLEANUP_GROUP_CANCEL_CALLBACK )
    ( void* ObjectContext, void* CleanupContext );

问题:如果您需要进行有根据的猜测,您认为ObjectContextCleanupContext会引用什么?

我的第一个猜测是CleanupContext是您在启动清理时指定的内容:因此第3个参数为CloseThreadpoolCleanupGroupMembers()。我非常有信心这个猜测是正确的,因为API调用直接相关。

我的第二个猜测是ObjectContext是您在提交work / io / timer项时指定的内容:这是CreateThreadpoolWork()等的第二个参数。我完全不确定是这种情况。

有人会认为这些猜测是正确的吗?有没有人以前使用过这个功能?

1 个答案:

答案 0 :(得分:2)

对于与调用CloseThreadpoolCleanupGroupMembers时尚未关闭的相同回调环境关联的每个对象,将调用您使用SetThreadpoolCallbackCleanupGroup函数指定的可选清理回调。回调的第一个参数,即对象上下文,是您在使用TrySubmitThreadpoolCallback,CreateThreadpoolWork等函数时指定的void *参数的值。回调的第二个参数,即清理上下文,是使用CloseThreadpoolCleanupGroupMembers函数时指定的void *参数的值。

要记住的重要一点是,是否为特定对象调用清理回调不依赖于该对象是否具有未完成的回调。它仅用于尚未关闭的对象。换句话说,完全有可能调用对象的回调,然后为同一个对象调用清理回调。

例如,如果使用CreateThreadpoolWork函数创建工作对象,并且在调用CloseThreadpoolCleanupGroupMembers之前无法调用CloseThreadpoolWork函数,则即使对象的回调已经执行,也将为该对象调用清理回调。未能调用CloseThreadpoolWork不是错误,因为CloseThreadpoolCleanupGroupMembers将关闭与清理组关联的任何对象。

需要注意的另一个问题是使用TrySubmitThreadpoolCallback函数。这是CreateThreadpoolWork的一个更简单的版本,因为您不必考虑创建,提交和关闭工作对象。诀窍是线程池在其回调执行后自动关闭工作对象。这意味着只有当该对象的回调仍处于挂起状态时才会调用该对象,并且在调用CloseThreadpoolCleanupGroupMembers以取消任何挂起的回调时指定TRUE。