【发布时间】:2021-10-29 13:33:33
【问题描述】:
我正在考虑使用 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();
BOOL bRet = FALSE;
printf("%d thread\n", threadId);
return;
}
int main() {
TP_CALLBACK_ENVIRON CallBackEnviron;
PTP_POOL pool = NULL;
PTP_CLEANUP_GROUP cleanupgroup = NULL;
PTP_WORK_CALLBACK workcallback = MyWorkCallback;
PTP_TIMER timer = NULL;
PTP_WORK work = NULL;
InitializeThreadpoolEnvironment(&CallBackEnviron);
pool = CreateThreadpool(NULL);
SetThreadpoolThreadMaximum(pool, 1);
SetThreadpoolThreadMinimum(pool, 3);
SetThreadpoolCallbackPool(&CallBackEnviron, pool);
for (int i = 0; i < 10; ++i) {
work = CreateThreadpoolWork(workcallback, NULL, &CallBackEnviron);
SubmitThreadpoolWork(work);
WaitForThreadpoolWorkCallbacks(work, FALSE); // This waits for the work item to get completed.
}
return 1;
}
这是一个简单的例子。在WaitForThreadpoolWorkCallbacks 上会发生什么我可以等待那个特定的工作项目。如果我做一些事情,这没问题。但是,如果我正在遍历一个目录并且有数千个文件需要对它们进行处理,我不想跟踪每个单独的工作项。是否可以查询线程池队列以查看是否有任何待处理的内容?或者找出是否有任何线程仍在工作?
【问题讨论】:
-
旁注: 为什么最大值设置为 1,最小值设置为 3?不应该反过来吗(例如,最大值为 3,最小值为 1)?来自:docs.microsoft.com/en-us/windows/win32/procthread/…你想要一个“清理组”吗?否则,全局(例如)
pendcnt怎么样?主/主线程在排队更多工作时[原子地]增加它。每个工作线程在完成一个工作项后都会递减这个值。排队 all 工作后的主线程可以 [原子地] 在pendcnt > 0上旋转。 -
是的,应该反过来。但是你的想法和我一样。我只是想到了这一点并将其放入我的 VS 代码中。下一个问题,是否有任何条件变量允许我 WaitForSingleObject 直到它达到 0?否则,我将不得不进行 while 循环,直到 pendcnt == 0。
-
警告: 我使用 linux/posix 线程,所以我只知道我在网上找到的内容。从我提到的链接中,为线程池设置一个清理组并调用
CloseThreadpoolCleanupGroupMembers可能会做到这一点。来自 cmets:等待所有回调完成。CloseThreadpoolCleanupGroupMembers也会释放属于清理组成员的对象,因此在调用CloseThreadpoolCleanupGroupMembers之后不必对单个对象调用 close 函数。 -
至于在
pendcnt上旋转,AFAICT,您需要与pthread_cond_wait等效的 win32。我发现:docs.microsoft.com/en-us/windows/win32/sync/condition-variables
标签: c windows multithreading