...
The fact that all threads will be awake solves the problem because each one ends up executing its predicate test; one will find its test to be true and will continue the execution until the end.
Compliant Solution (Windows, Condition Variables)
This compliant solution uses a CONDITION_VARIABLE
object, available on Microsoft Windows Vista and later).
Code Block | ||||
---|---|---|---|---|
| ||||
#include <Windows.h>
#include <stdio.h>
CRITICAL_SECTION lock;
CONDITION_VARIABLE cond;
DWORD WINAPI run_step(LPVOID t) {
static int current_step = 0;
int my_step = (int)t;
int result;
EnterCriticalSection(&lock);
printf("Thread %d has the lock\n", my_step);
while (current_step != my_step) {
printf("Thread %d is sleeping...\n", my_step);
if (!SleepConditionVariableCS(&cond, &lock, INFINITE)) {
/* Handle error condition */
}
printf("Thread %d woke up\n", my_step);
}
/* Do processing... */
printf("Thread %d is processing...\n", my_step);
current_step++;
LeaveCriticalSection(&lock);
/* Signal ALL waiting tasks */
WakeAllConditionVariable(&cond);
printf("Thread %d is exiting...\n", my_step);
return 0;
}
enum { NTHREADS = 5 };
int main(int argc, char** argv) {
int i;
HANDLE threads[NTHREADS];
InitializeCriticalSection(&lock);
InitializeConditionVariable(&cond);
/* Create threads */
for (i = 0; i < NTHREADS; i++) {
threads[i] = CreateThread(NULL, 0, run_step, (LPVOID)i, 0, 0);
}
/* Wait for all threads to complete */
WaitForMultipleObjects(NTHREADS, threads, TRUE, INFINITE);
DeleteCriticalSection(&lock);
return 0;
} |
Compliant Solution (Using cnd_signal()
but with a Unique Condition Variable per Thread)
...
...