...
Deadlock: Out-of-Sequence Step Value
Time | Thread # |
| Action |
|---|---|---|---|
0 | 3 | 0 | Thread 3 executes the first time: the predicate is |
1 | 2 | 0 | Thread 2 executes the first time: the predicate is |
2 | 4 | 0 | Thread 4 executes the first time: the predicate is |
3 | 0 | 0 | Thread 0 executes the first time: the predicate is |
4 | 1 | 1 | Thread 1 executes the first time: the predicate is |
5 | 3 | 2 | Thread 3 wakes up (scheduler choice): the predicate is |
6 | — | — | Thread exhaustion! There are no more threads to run, and a conditional variable signal is needed to wake up the others. |
This noncompliant code example violates the liveness property.
...
This compliant solution uses notify_all() to signal all waiting threads instead of a single random thread. Only the run_step() thread code from the noncompliant code example is modified, as modified.
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
std::mutex mutex;
std::condition_variable cond;
void run_step(size_t myStep) {
static size_t currentStep = 0;
std::unique_lock<std::mutex> lk(mutex);
std::cout << "Thread " << myStep << " has the lock" << std::endl;
while (currentStep != myStep) {
std::cout << "Thread " << myStep << " is sleeping..." << std::endl;
cond.wait(lk);
std::cout << "Thread " << myStep << " woke up" << std::endl;
}
// Do processing ...
std::cout << "Thread " << myStep << " is processing..." << std::endl;
currentStep++;
// Signal ALL waiting tasks.
cond.notify_all();
std::cout << "Thread " << myStep << " is exiting..." << std::endl;
}
// ... main() unchanged ... |
...
Failing to preserve the thread safety and liveness of a program when using condition variables can lead to indefinite blocking and denial of service (DoS).
Rule | Severity | Likelihood | Detectable |
|---|
Repairable | Priority | Level | |
|---|---|---|---|
CON55-CPP | Low | Unlikely | No |
Yes | P2 | L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
|---|---|---|---|---|---|---|---|---|---|
| CodeSonar |
| CONCURRENCY.BADFUNC.CNDSIGNAL | Use of Condition Variable Signal | ||||||
| Helix QAC |
| C++1778, C++1779 | |||||||
| Klocwork |
| CERT.CONC.UNSAFE_COND_VAR | |||||||
| Parasoft C/C++test |
| CERT_CPP-CON55-a | Do not use the 'notify_one()' function when multiple threads are waiting on the same condition variable | ||||||
| Polyspace Bug Finder |
| Checks for multiple threads waiting for same condition variable (rule fully covered) |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
Bibliography
| [IEEE Std 1003.1:2013] | XSH, System Interfaces, pthread_cond_broadcastXSH, System Interfaces, pthread_cond_signal |
| [Lea 2000] |
...
...