【问题标题】:Cancelling scheduled work/io/timer items in WIN32 thread pool取消WIN32线程池中的计划工作/io/定时器项
【发布时间】:2011-05-12 08:21:39
【问题描述】:

我一直在玩 Windows 的(新的?)线程池 API。我一直在遵循Using the Thread Pool Functions 中的示例,并且一直在认真研究 MSDN 上的 API。关于清理小组,我有些不明白。

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

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

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

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

将法律掌握在自己手中,我将定义追溯到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 是您在启动清理时指定的:因此是CloseThreadpoolCleanupGroupMembers() 的第三个参数。我很有信心这个猜测是正确的,因为 API 调用是如此直接相关。

我的第二个猜测是ObjectContext 是您在提交工作/io/计时器项时指定的:这是CreateThreadpoolWork() 等人的第二个参数。我完全不确定情况是否如此。

有人可以证实这些猜测是正确的吗?有人用过这个功能吗?

【问题讨论】:

    标签: c++ c windows multithreading threadpool


    【解决方案1】:

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

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

    例如,如果您使用 CreateThreadpoolWork 函数创建了一个工作对象,并且在调用 CloseThreadpoolCleanupGroupMembers 之前未能调用 CloseThreadpoolWork 函数,那么即使对象的回调已经执行,也会为该对象调用清理回调。调用 CloseThreadpoolWork 失败不是错误,因为 CloseThreadpoolCleanupGroupMembers 将关闭与清理组关联的所有对象。

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

    【讨论】:

    • 谢谢!我昨天发布问题后进行的一个简单测试证实了我对指针的猜测,但我很高兴我等待你的回答。我确实误解了一些与创建/提交/关闭工作对象有关的文档,并且想知道为什么要为 所有 我的工作对象调用清理。
    猜你喜欢
    • 2012-08-12
    • 2016-01-08
    • 2021-02-24
    • 2018-01-20
    • 1970-01-01
    • 1970-01-01
    • 2020-05-23
    • 2021-08-08
    • 1970-01-01
    相关资源
    最近更新 更多