...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <stdio.h>
#include <threads.h>
enum { NTHREADS = 5 };
mtx_t mutex;
cnd_t cond;
int run_step(void *t) {
static int current_step = 0;
size_t my_step = *(size_t *)t;
if (thrd_success != mtx_lock(&mutex)) {
/* Handle error */
}
printf("Thread %d%zu has the lock\n", my_step);
while (current_step != my_step) {
printf("Thread %d%zu is sleeping...\n", my_step);
if (thrd_success != cnd_wait(&cond, &mutex)) {
/* Handle error */
}
printf("Thread %d%zu woke up\n", my_step);
}
/* Do processing ... */
printf("Thread %d%zu is processing...\n", my_step);
current_step++;
/* Signal awaiting task */
if (thrd_success != cnd_signal(&cond)) {
/* Handle error */
}
printf("Thread %d%zu is exiting...\n", my_step);
if (thrd_success != mtx_unlock(&mutex)) {
/* Handle error */
}
return 0;
}
int main(void) {
thrd_t threads[NTHREADS];
size_t step[NTHREADS];
if (thrd_success != mtx_init(&mutex, mtx_plain)) {
/* Handle error */
}
if (thrd_success != cnd_init(&cond)) {
/* Handle error */
}
/* Create threads */
for (size_t i = 0; i < NTHREADS; ++i) {
step[i] = i;
if (thrd_success != thrd_create(&threads[i], run_step,
&step[i])) {
/* Handle error */
}
}
/* Wait for all threads to complete */
for (size_t i = NTHREADS; i != 0; --i) {
if (thrd_success != thrd_join(threads[i-1], NULL)) {
/* Handle error */
}
}
mtx_destroy(&mutex);
cnd_destroy(&cond);
return 0;
} |
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <stdio.h> #include <threads.h> mtx_t mutex; cnd_t cond; int run_step(void *t) { static size_t current_step = 0; size_t my_step = *(size_t *)t; if (thrd_success != mtx_lock(&mutex)) { /* Handle error */ } printf("Thread %d%zu has the lock\n", my_step); while (current_step != my_step) { printf("Thread %d%zu is sleeping...\n", my_step); if (thrd_success != cnd_wait(&cond, &mutex)) { /* Handle error */ } printf("Thread %d%zu woke up\n", my_step); } /* Do processing ... */ printf("Thread %d%zu is processing...\n", my_step); current_step++; /* Signal ALL waiting tasks */ if (thrd_success != cnd_broadcast(&cond)) { /* Handle error */ } printf("Thread %d%zu is exiting...\n", my_step); if (thrd_success != mtx_unlock(&mutex)) { /* Handle error */ } return 0; } |
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <stdio.h>
#include <threads.h>
enum { NTHREADS = 5 };
mtx_t mutex;
cnd_t cond[NTHREADS];
int run_step(void *t) {
static size_t current_step = 0;
size_t my_step = *(size_t *)t;
if (thrd_success != mtx_lock(&mutex)) {
/* Handle error */
}
printf("Thread %d%zu has the lock\n", my_step);
while (current_step != my_step) {
printf("Thread %d%zu is sleeping...\n", my_step);
if (thrd_success != cnd_wait(&cond[my_step], &mutex)) {
/* Handle error */
}
printf("Thread %d%zu woke up\n", my_step);
}
/* Do processing ... */
printf("Thread %d%zu is processing...\n", my_step);
current_step++;
/* Signal next step thread */
if ((my_step + 1) < NTHREADS) {
if (thrd_success != cnd_signal(&cond[my_step + 1])) {
/* Handle error */
}
}
printf("Thread %d%zu is exiting...\n", my_step);
if (thrd_success != mtx_unlock(&mutex)) {
/* Handle error */
}
return 0;
}
int main(void) {
thrd_t threads[NTHREADS];
size_t step[NTHREADS];
if (thrd_success != mtx_init(&mutex, mtx_plain)) {
/* Handle error */
}
for (size_t i = 0; i< NTHREADS; ++i) {
if (thrd_success != cnd_init(&cond[i])) {
/* Handle error */
}
}
/* Create threads */
for (size_t i = 0; i < NTHREADS; ++i) {
step[i] = i;
if (thrd_success != thrd_create(&threads[i], run_step,
&step[i])) {
/* Handle error */
}
}
/* Wait for all threads to complete */
for (size_t i = NTHREADS; i != 0; --i) {
if (thrd_success != thrd_join(threads[i-1], NULL)) {
/* Handle error */
}
}
mtx_destroy(&mutex);
for (size_t i = 0; i < NTHREADS; ++i) {
cnd_destroy(&cond[i]);
}
return 0;
} |
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <Windows.h>
#include <stdio.h>
CRITICAL_SECTION lock;
CONDITION_VARIABLE cond;
DWORD WINAPI run_step(LPVOID t) {
static size_t current_step = 0;
size_t my_step = (size_t)t;
EnterCriticalSection(&lock);
printf("Thread %d%zu has the lock\n", my_step);
while (current_step != my_step) {
printf("Thread %d%zu is sleeping...\n", my_step);
if (!SleepConditionVariableCS(&cond, &lock, INFINITE)) {
/* Handle error */
}
printf("Thread %d%zu woke up\n", my_step);
}
/* Do processing ... */
printf("Thread %d%zu is processing...\n", my_step);
current_step++;
LeaveCriticalSection(&lock);
/* Signal ALL waiting tasks */
WakeAllConditionVariable(&cond);
printf("Thread %d%zu is exiting...\n", my_step);
return 0;
}
enum { NTHREADS = 5 };
int main(void) {
HANDLE threads[NTHREADS];
InitializeCriticalSection(&lock);
InitializeConditionVariable(&cond);
/* Create threads */
for (size_t i = 0; i < NTHREADS; ++i) {
threads[i] = CreateThread(NULL, 0, run_step, (LPVOID)i, 0, NULL);
}
/* Wait for all threads to complete */
WaitForMultipleObjects(NTHREADS, threads, TRUE, INFINITE);
DeleteCriticalSection(&lock);
return 0;
} |
...
| CERT Oracle Secure Coding Standard for Java | THI02-J. Notify all waiting threads rather than a single thread |
Bibliography
| [IEEE Std 1003.1:2013] | XSH, System Interfaces, pthread_cond_broadcastXSH, System Interfaces, pthread_cond_signal |
| [Lea 2000] |
...