Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Added a Windows compliant solution

...

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
bgColor#ccccff
langc
#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)

...

 

...