Skip to content

[BUG] Deadlock on pool exit #93

@alugowski

Description

@alugowski

I'm seeing a deadlock upon thread pool destruction:

Screenshot 2023-01-09 at 8 37 07 PM

Screenshot 2023-01-09 at 8 38 00 PM

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)

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions