如何查询Windows Thread Pool队列状态判断所有提交工作项是否完成
解决方案
Windows线程池原生提供了清理组(Cleanup Group) 机制,无需单独维护每个工作项的句柄,就能批量等待所有提交的工作项全部执行完成,完全适配数千甚至上万个工作项的批量处理场景。
实现步骤
- 创建自定义线程池后,调用
CreateThreadpoolCleanupGroup创建清理组 - 调用
SetThreadpoolCallbackCleanupGroup将清理组绑定到当前的回调环境中,后续所有在该环境下创建的工作项都会自动被清理组管理 - 所有工作项提交完成后,调用
CloseThreadpoolCleanupGroupMembers即可等待所有工作项全部执行完毕,无需单独追踪每个工作项的状态
注:Windows线程池未对外公开查询队列待处理任务、运行中线程状态的官方API,清理组是微软官方推荐的批量等待线程池任务的最优方案,性能开销可忽略。
修改后的示例代码
#include <windows.h> #include <tchar.h> #include <stdio.h> VOID CALLBACK MyWorkCallback(PTP_CALLBACK_INSTANCE Instance, PVOID Parameter, PTP_WORK Work) { DWORD threadId = GetCurrentThreadId(); printf("%d thread 执行任务\n", threadId); // 工作项执行完成后可直接释放work对象 CloseThreadpoolWork(Work); return; } int main() { TP_CALLBACK_ENVIRON CallBackEnviron; PTP_POOL pool = NULL; PTP_CLEANUP_GROUP cleanupgroup = NULL; PTP_WORK_CALLBACK workcallback = MyWorkCallback; PTP_WORK work = NULL; // 初始化回调环境、创建线程池 InitializeThreadpoolEnvironment(&CallBackEnviron); pool = CreateThreadpool(NULL); // 注意原代码逻辑错误:最大线程数不能小于最小线程数,此处做了修正 SetThreadpoolThreadMaximum(pool, 8); SetThreadpoolThreadMinimum(pool, 3); SetThreadpoolCallbackPool(&CallBackEnviron, pool); // 初始化清理组并绑定到回调环境 cleanupgroup = CreateThreadpoolCleanupGroup(); SetThreadpoolCallbackCleanupGroup(&CallBackEnviron, cleanupgroup, NULL); // 批量提交工作项,无需保存每个work的句柄 for (int i = 0; i < 1000; ++i) { work = CreateThreadpoolWork(workcallback, NULL, &CallBackEnviron); SubmitThreadpoolWork(work); // 不需要单独等待每个工作项完成 } // 等待所有工作项全部执行完成,第二个参数传FALSE表示不取消未运行的任务,全部执行完再返回 CloseThreadpoolCleanupGroupMembers(cleanupgroup, FALSE, NULL); // 资源释放 CloseThreadpoolCleanupGroup(cleanupgroup); DestroyThreadpoolEnvironment(&CallBackEnviron); CloseThreadpool(pool); printf("所有工作项已全部执行完成\n"); return 0; }
关键API说明
CloseThreadpoolCleanupGroupMembers第二个参数:传TRUE会直接取消所有未执行的工作项立即返回,传FALSE会阻塞等待所有已提交的工作项全部执行完成后才返回。- 绑定清理组后,工作项对象可以在回调函数执行完成后直接调用
CloseThreadpoolWork释放,也可以在调用CloseThreadpoolCleanupGroupMembers时统一释放,无需单独维护。
内容的提问来源于stack exchange,提问作者Quick33
相关产品推荐
相关产品推荐

