/******************************************************** * An example source module to accompany... * * "Using POSIX Threads: Programming with Pthreads" * by Brad nichols, Dick Buttlar, Jackie Farrell * O'Reilly & Associates, Inc. * ******************************************************** * simple_mutex.c * * Simple multi-threaded example with a mutex lock. * Does the same as the example above (see the link below) * but with mutual exclusion. Any time a thread starts, it * request the thread lock. Just one thread is executing * anytime. The others must wait it to unlock before proceeding. * quickly comment out by Mij <mij@bitchx.it> for * http://mij.oltrelinux.com/devel/unixprg/ * * (also modified a bit on the code itself for clarity and * expressiveness purposes) */ #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <pthread.h> void do_one_thing(int *); /* first thread */ void do_another_thing(int *); /* second thread */ void do_wrap_up(int, int); int r1 = 0, r2 = 0, r3 = 0; pthread_mutex_t r3_mutex=PTHREAD_MUTEX_INITIALIZER; /* for mutex locking */ extern int main(int argc, char **argv) { /* thread ids */ pthread_t thread1, thread2; if (argc > 1) r3 = atoi(argv[1]); /* creating the first thread */ if (pthread_create(&thread1, NULL, (void *) do_one_thing, (void *) &r1) != 0) perror("pthread_create"),exit(1); /* creating the second thread */ if (pthread_create(&thread2, NULL, (void *) do_another_thing, (void *) &r2) != 0) perror("pthread_create"),exit(1); /* expecting the first thread to terminate */ if (pthread_join(thread1, NULL) != 0) perror("pthread_join"), exit(1); /* expecting the second thread to terminate */ if (pthread_join(thread2, NULL) != 0) perror("pthread_join"), exit(1); do_wrap_up(r1, r2); return 0; } void do_one_thing(int *pnum_times) { int i, j, x; pthread_t ti; ti = pthread_self(); /* which's our id? */ pthread_mutex_lock(&r3_mutex); /* this is the segment containing sensitive operations. * So we need to keep it alone from concurrency for safeness. */ if(r3 > 0) { x = r3; r3--; } else { x = 1; } /* sensitive code end */ pthread_mutex_unlock(&r3_mutex); for (i = 0; i < 4; i++) { printf("doing one thing\n"); for (j = 0; j < 10000; j++) x = x + i; printf("thread %d: got x = %d\n", (int)ti, x); (*pnum_times)++; } } void do_another_thing(int *pnum_times) { int i, j, x; pthread_t ti; ti = pthread_self(); pthread_mutex_lock(&r3_mutex); if(r3 > 0) { x = r3; r3--; } else { x = 1; } pthread_mutex_unlock(&r3_mutex); for (i = 0; i < 4; i++) { printf("doing another \n"); for (j = 0; j < 10000; j++) x = x + i; printf("thread %d: got x = %d\n", (int)ti, x); (*pnum_times)++; } } void do_wrap_up(int one_times, int another_times) { int total; total = one_times + another_times; printf("All done, one thing %d, another %d for a total of %d\n", one_times, another_times, total); }