/************************************************************ * file: thread.cc * Visualization Course, Fall 2001 * Author: Ting-Jen Yen (yentj@cs.nyu.edu), modified by Chee * * A basic demo of posix threads. * In this simple example, we only create one thread (called * the "child thread". The main program serves as the * other thread, "main thread". * The two thread are trying to increment a shared variable * "a" for N=8 and M=12 times (resp.) each. To ensure mutual * exclusion, it must first grab a mutex variable (mutex1) * before incrementing a. At the end of the * program, the value of a should be N+M = 20. * But the order in which the 2 threads access a is * unpredictable. * * Compile with * cygwin: > gcc $(OPT) thread.c -o thread * solaris: > gcc $(OPT) -lpthread -lposix4 thread.c -o thread * * NOTE: If OPT is the empty string (or undefined), then the child * thread will be scheduled more aggressively than the main * thread. But if OPT = -D_YIELD, then both threads will be * scheduled equally. See the code below to see why this is so. * ************************************************************/ #include #include #include #include #include void * mythread(void *); // forward declaration void mainFunc(void); // forward declaration pthread_mutex_t mutex1; // mutex object int a; // shared variable /************************************************************ Main Program ************************************************************/ main() { pthread_t p_id; // thread object pthread_create(&p_id, NULL, mythread, NULL); // create it pthread_mutex_init(&mutex1, NULL); // initialize mutex object a= 0; mainFunc(); // the "main thread" pthread_join(p_id, NULL); // wait for child thread to end } /************************************************************ Child Thread ************************************************************/ void * mythread(void *rt) { int i; puts("Child thread starts"); for (i = 0 ; i < 8; i ++) { pthread_mutex_lock(&mutex1); // grab mutex1 a ++; // increment "a" printf("Child thread: a = %d\n", a); // prints "a" pthread_mutex_unlock(&mutex1); // release mutex1 #ifdef _YIELD sched_yield(); // gives fairer scheduling #endif } puts("Child thread done"); pthread_exit(NULL); }// mythread /************************************************************ Main Thread Function ************************************************************/ void mainFunc(void) { char s[80]; int i=0; puts("Main thread starts"); for (i = 0 ; i < 12; i ++) { pthread_mutex_lock(&mutex1); // enter critical section a ++; printf("Main Thread: a = %d\n", a); pthread_mutex_unlock(&mutex1); // exit critical section #ifdef _YIELD sched_yield(); // main thread always yields #endif } puts("Main thread done"); pthread_mutex_destroy(&mutex1); }//mainFunc /************************************************************ END ************************************************************/