The following program creates many threads running concurrently. All of them share the same global counter variable. Of these many threads, one of them is a counting thread that keeps increasing the counter, while all the others keep retrieving and displaying the value of the shared counter.
Click here to download a copy of this program.
#include <stdio.h> #include <stdlib.h> #include <thread.h> #define MAX_THREADS 10 int MaxIteration; int Counter = 0; void *Display(void *ID) { int *intPTR = (int *) ID; int MyID = *intPTR; int i; for (i = 1; i <= MaxIteration/2; i++) printf("Thread %d reporting --> %d\n", MyID, Counter); printf("Thread %d is done....\n", MyID); thr_exit(0); } void *Counting(void *ID) { int i; while (1) { /* this is an infinite loop */ Counter++; if (Counter % 10 == 0) printf("\t\tFrom Counting(): counter = %d\n", Counter); } } void main(int argc, char *argv[]) { thread_t ID[MAX_THREADS]; size_t Status; int NoThreads, i, No[MAX_THREADS]; if (argc != 3) { printf("Use %s #-of-threads #-of-iterations\n", argv[0]); exit(1); } NoThreads = abs(atoi(argv[1])); MaxIteration = abs(atoi(argv[2])); if (NoThreads > MAX_THREADS) { printf("*** ERROR: too many threads ***\n"); exit(0); } thr_create(NULL, 0, Counting, (void *) NULL, 0, NULL); for (i = 0; i < NoThreads; i++) { printf("Parent: about to create thread %d\n", i); No[i] = i; thr_create(NULL, 0, Display, (void *) (&(No[i])), 0, &(ID[i])); } for (i = 0; i < NoThreads; i++) thr_join(ID[i], 0, (void *) &Status); }
Why is an array No[] used in the call to thr_create()? Could we just use a variable? In fact, we cannot use a variable. Here is why. If the call is changed tofor (i = 0; i < NoThreads; i++) { printf("Parent: about to create thread %d\n", i); No[i] = i; thr_create(NULL, 0, Display, (void *) (&(No[i])), 0, &(ID[i])); }
then before the newly created thread takes the value of i, the for loop could come back and increases the value of i. As a result, the newly created thread will receive an incorrect value. This is why an array rather than a variable is used in the call.for (i = 0; i < NoThreads; i++) { printf("Parent: about to create thread %d\n", i); thr_create(NULL, 0, Display, (void *) (&i), 0, &(ID[i])); }