使用 CreateThreadpoolWork/SubmitThreadpoolWork 时将不同的值传递给回调函数
Pass different values to callback function when using CreateThreadpoolWork/ SubmitThreadpoolWork
我目前正在学习 Threadpool API 作为 WinAPI 的一部分。我成功地创建了一个线程池并使用 SubmitThreadpoolWork
来执行工作线程。但是,到目前为止,我只能将一个静态值传递给所有工作线程(指定为 CreateThreadpoolWork
函数的 2. 参数)。如何将不同的值传递给每个工作线程?
我的回调函数:
void CALLBACK test(PTP_CALLBACK_INSTANCE Instance, PVOID Parameter, PTP_WORK Work) {
Sleep(2000);
int* val = (int*)Parameter;
std::wcout << (*val) << std::endl;
}
我的主要功能:
int main() {
TP_CALLBACK_ENVIRON callBackEnviron;
PTP_POOL pool = NULL;
PTP_CLEANUP_GROUP cleanupgroup = NULL;
PTP_WORK_CALLBACK workcallback = test;
PTP_TIMER timer = NULL;
PTP_WORK work = NULL;
InitializeThreadpoolEnvironment(&callBackEnviron);
pool = CreateThreadpool(NULL);
SetThreadpoolThreadMaximum(pool, 8);
cleanupgroup = CreateThreadpoolCleanupGroup();
SetThreadpoolCallbackPool(&callBackEnviron, pool);
SetThreadpoolCallbackCleanupGroup(&callBackEnviron, cleanupgroup, NULL);
for (int i = 0; i < 20; ++i)
{
work = CreateThreadpoolWork(workcallback, &i, &callBackEnviron);
SubmitThreadpoolWork(work);
}
WaitForThreadpoolWorkCallbacks(work, FALSE);
CloseThreadpoolWork(work);
CloseThreadpoolCleanupGroupMembers(cleanupgroup, FALSE, NULL);
CloseThreadpoolCleanupGroup(cleanupgroup);
CloseThreadpool(pool);
}
请注意,每个工作线程输出“20”,这是 i
在 for-loop
完成之前的最终值。但是,我希望每个工作线程在执行相应的 SubmitThreadpoolWork
调用时输出 i
的值。我也很确定 CreateThreadpoolWork
不应该在循环中调用,但我不确定如何尝试否则。
您正在向每个工作项传递一个指向循环计数器变量的指针。该变量将超出范围并在循环结束时被销毁。因此,在此时间之前 运行 的所有工作人员都将作用于共享内存,而在那之后 运行 的任何工作人员将作用于指向无效内存的悬空指针,即 未定义的行为.
您需要:
- 为每个工作人员动态分配一个新变量,并在回调中释放该变量:
void CALLBACK test(PTP_CALLBACK_INSTANCE Instance, PVOID Parameter, PTP_WORK Work) {
Sleep(2000);
int* val = static_cast<int*>(Parameter);
std::wcout << *val << std::endl;
delete val;
}
for (int i = 0; i < 20; ++i)
{
int *val = new int(i);
work = CreateThreadpoolWork(workcallback, val, &CallBackEnviron);
if (work)
SubmitThreadpoolWork(work);
else
delete val;
}
- 将整数的 value 类型转换为指针,然后在回调中将其类型转换回整数:
void CALLBACK test(PTP_CALLBACK_INSTANCE Instance, PVOID Parameter, PTP_WORK Work) {
Sleep(2000);
int val = reinterpret_cast<int>(Parameter);
std::wcout << val << std::endl;
}
for (int i = 0; i < 20; ++i)
{
work = CreateThreadpoolWork(workcallback, reinterpret_cast<void*>(i), &CallBackEnviron);
if (work)
SubmitThreadpoolWork(work);
}
我目前正在学习 Threadpool API 作为 WinAPI 的一部分。我成功地创建了一个线程池并使用 SubmitThreadpoolWork
来执行工作线程。但是,到目前为止,我只能将一个静态值传递给所有工作线程(指定为 CreateThreadpoolWork
函数的 2. 参数)。如何将不同的值传递给每个工作线程?
我的回调函数:
void CALLBACK test(PTP_CALLBACK_INSTANCE Instance, PVOID Parameter, PTP_WORK Work) {
Sleep(2000);
int* val = (int*)Parameter;
std::wcout << (*val) << std::endl;
}
我的主要功能:
int main() {
TP_CALLBACK_ENVIRON callBackEnviron;
PTP_POOL pool = NULL;
PTP_CLEANUP_GROUP cleanupgroup = NULL;
PTP_WORK_CALLBACK workcallback = test;
PTP_TIMER timer = NULL;
PTP_WORK work = NULL;
InitializeThreadpoolEnvironment(&callBackEnviron);
pool = CreateThreadpool(NULL);
SetThreadpoolThreadMaximum(pool, 8);
cleanupgroup = CreateThreadpoolCleanupGroup();
SetThreadpoolCallbackPool(&callBackEnviron, pool);
SetThreadpoolCallbackCleanupGroup(&callBackEnviron, cleanupgroup, NULL);
for (int i = 0; i < 20; ++i)
{
work = CreateThreadpoolWork(workcallback, &i, &callBackEnviron);
SubmitThreadpoolWork(work);
}
WaitForThreadpoolWorkCallbacks(work, FALSE);
CloseThreadpoolWork(work);
CloseThreadpoolCleanupGroupMembers(cleanupgroup, FALSE, NULL);
CloseThreadpoolCleanupGroup(cleanupgroup);
CloseThreadpool(pool);
}
请注意,每个工作线程输出“20”,这是 i
在 for-loop
完成之前的最终值。但是,我希望每个工作线程在执行相应的 SubmitThreadpoolWork
调用时输出 i
的值。我也很确定 CreateThreadpoolWork
不应该在循环中调用,但我不确定如何尝试否则。
您正在向每个工作项传递一个指向循环计数器变量的指针。该变量将超出范围并在循环结束时被销毁。因此,在此时间之前 运行 的所有工作人员都将作用于共享内存,而在那之后 运行 的任何工作人员将作用于指向无效内存的悬空指针,即 未定义的行为.
您需要:
- 为每个工作人员动态分配一个新变量,并在回调中释放该变量:
void CALLBACK test(PTP_CALLBACK_INSTANCE Instance, PVOID Parameter, PTP_WORK Work) {
Sleep(2000);
int* val = static_cast<int*>(Parameter);
std::wcout << *val << std::endl;
delete val;
}
for (int i = 0; i < 20; ++i)
{
int *val = new int(i);
work = CreateThreadpoolWork(workcallback, val, &CallBackEnviron);
if (work)
SubmitThreadpoolWork(work);
else
delete val;
}
- 将整数的 value 类型转换为指针,然后在回调中将其类型转换回整数:
void CALLBACK test(PTP_CALLBACK_INSTANCE Instance, PVOID Parameter, PTP_WORK Work) {
Sleep(2000);
int val = reinterpret_cast<int>(Parameter);
std::wcout << val << std::endl;
}
for (int i = 0; i < 20; ++i)
{
work = CreateThreadpoolWork(workcallback, reinterpret_cast<void*>(i), &CallBackEnviron);
if (work)
SubmitThreadpoolWork(work);
}