使用 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”,这是 ifor-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);
}