代码之家  ›  专栏  ›  技术社区  ›  André Caron

取消WIN32线程池中的计划工作/io/timer项

  •  1
  • André Caron  · 技术社区  · 14 年前

    我一直在玩窗户(新的?)线程池API。我一直在学习 Using the Thread Pool Functions 我仔细查看了MSDN上的API。我对清理小组有些不了解。

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

    在释放关联对象之前取消清理组时要调用的清理回调。当您调用 CloseThreadpoolCleanupGroupMembers() .

    如果我的理解是正确的,这意味着您可以取消挂起的work/io/timer项,并要求它对这些对象中的每个对象调用cleanup回调函数 相反 初始队列work/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 );
    

    问题 :如果你不得不接受有根据的猜测,你认为 ObjectContext CleanupContext 参考?

    我的第一个猜测是 清除上下文 是在启动清理时指定的:因此 CloseThreadpoolCleanupGroupMembers() . 我非常确信这个猜测是正确的,因为API调用是如此直接相关。

    我的第二个猜测是 对象上下文 是在提交work/io/timer项时指定的:这是 CreateThreadpoolWork() 等。我完全不确定是不是这样。

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

    1 回复  |  直到 13 年前
        1
  •  2
  •   Kenny Kerr    14 年前

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

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

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

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