February 5th, 2024

How can I close a thread pool and cancel all work that had been queued to it?

When you close a custom Win32 thread pool, the call to Close­Threadpool returns immediately, but the actual closure doesn’t occur until all pending work has completed. What if you want to abandon any work that hasn’t yet begun?

What you can do is put the work items in a thread pool cleanup group, and when you want to abandon all of the pending callbacks, call Close­Threadpool­Cleanup­Group­Members and pass TRUE for fCancel­Pending­Callbacks. The function abandons any callbacks that haven’t started but waits for for callbacks that have already started.¹

Here’s a sample, with no error checking.

auto pool = CreateThreadpool(0);
auto group = CreateThreadpoolCleanupGroup();

TP_CALLBACK_ENVIRON env;
InitializeThreadpoolEnvironment(&env);
SetThreadpoolCallbackPool(&env, pool);
SetThreadpoolCallbackCleanupGroup(&env, group, nullptr);

// Queue up 100 slow-running tasks.
auto callback = [](auto instance, auto context, auto work)
    {
        printf("%d\n", PtrToInt(context));
        Sleep(100);
    };
for (int i = 0; i < 100; i++)
{
    auto work = CreateThreadpoolWork(callback, IntToPtr(i), &env);
    SubmitThreadpoolWork(work);
}

// Shut down the entire group.
// Any callbacks that haven't started will be abandoned.
CloseThreadpoolCleanupGroupMembers(group, TRUE, nullptr);

// Clean up the thread pool when done.
CloseThreadpool(pool);

¹ If you want the ones that have already started to respond to the shutdown, you can create a custom signal and have each callback explicitly periodically check that custom signal themselves.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

1 comment

Discussion is closed. Login to edit/delete existing comments.

  • Jan RingoÅ¡

    The Vista thread pool is extremely fun to abstract into C++. So many opportunities for a callback to complete on object that’s long gone. So many opportunities for deadlocks.