Anonymous Entity
Anonymous Entity

Reputation: 3350

condition_variable not always working

It seems like condition_variable notify_one doesn't always work the way it should.

struct Task {
    std::mutex mutex;
    std::condition_variable cv;
    std::atomic_bool launch{false};
};
void job(Task& task) {
    std::unique_lock<std::mutex> lock{task.mutex};
    task.cv.wait(lock, [&]{ return task.launch == true; });
}
int main() {
    for (auto i=0 ; i<1000*1000 ; i++) {
        Task task;
        std::thread thread{job, std::ref(task)};
        task.launch = true;
        task.cv.notify_one();
        thread.join();
    }
}

This program will almost never reach the end, it stops forever in the loop a vast majority of the time. Why does that happen?

Upvotes: 1

Views: 670

Answers (2)

Ulrich Eckhardt
Ulrich Eckhardt

Reputation: 17415

Two mistakes here:

  • If you sync access to an object, you don't need atomic types for that object. Your atomic_bool just causes overhead.
  • If you want to sync access to the launch flag, you need to lock its mutex before writing to it. You don't do that in main().

Explanation:

  1. main() creates task
  2. main() creates thread
  3. job() locks the mutex
  4. job() checks launch, which is false
  5. main() sets launch
  6. main() signals the CV, which nobody receives
  7. job() waits for the CV due to the value of launch in step 4

Normally, steps 3 and 6 would be atomic because any other thread should not have touched launch without locking the mutex. Since that didn't happen, the interleaving of dependent operations was allowed to take place, which finally caused the unexpected behaviour.

Upvotes: 4

Jean-Baptiste Yun&#232;s
Jean-Baptiste Yun&#232;s

Reputation: 36401

Not clear what you want, but your problem is that is may happen that the main realizes launch=true and notify_one() before the thread had time to call wait. In this case, you should know that notify is not delayed, thus your main will be blocked on join while the thread is blocked on wait.

Upvotes: 1

Related Questions