-
Notifications
You must be signed in to change notification settings - Fork 286
Description
I'm seeing a deadlock upon thread pool destruction:
My workload creates a thread pool for one expensive operation. Tasks are not created all at once, instead more are created as old ones finish. wait_for_tasks()
makes no difference.
There appears to be one worker thread left waiting for the condition variable as the thread is being joined.
I haven't managed to reproduce it with a small program yet. This is one actual use that suffers the issue:
https://github.com/alugowski/fast_matrix_market/blob/main/include/fast_matrix_market/write_body_threads.hpp
That code is exercised by my unit tests. If I loop a unit test a few thousand times then it nearly always deadlocks.
Workaround:
The following hack works around the issue. Replace the worker thread's wait()
with a wait_until
and a duration. This way it won't deadlock for more than about 50ms. The break condition must be rechecked afterwards.
task_available_cv.wait_until(tasks_lock, std::chrono::system_clock::now() + 50ms, [this] { return !tasks.empty() || !running; });
if (running)
{
if (tasks.empty()) {
continue;
}
Sounds related to #76.
- CPU model, architecture, # of cores and threads: M1 Pro, 8 cores
- Operating system: macOS 13
- Name and version of C++ compiler: Clang 15 from homebrew
- Thread pool library version: 3.3.0 (light version)