/* * This program ends up in a threadrace when the argument is around 1M * * We need synchronization primitives to help here! */ #include #include #include struct args { int max; char letter; pthread_mutex_t* mutex; }; volatile int counter = 0; void* count_thread(void* arg) { struct args* a = arg; for (int i = 0; i < a->max; i++) { pthread_mutex_lock(a->mutex); counter = counter + 1; pthread_mutex_unlock(a->mutex); } // // But given this process is pretty fast... this is better // pthread_mutex_lock(a->mutex); // for (int i = 0; i < a->max; i++) { // counter = counter + 1; // } // pthread_mutex_unlock(a->mutex); printf("Thread %c: done with counter at %d\n", a->letter, counter); return NULL; } void* make_args(int max, char letter, pthread_mutex_t* mutex) { struct args* a = malloc(sizeof(struct args)); a->max = max; a->letter = letter; a->mutex = mutex; return (void*) a; } int main(int argc, char* argv[]) { if (argc != 2) { exit(1); } int max = atoi(argv[1]); pthread_mutex_t* mutex = malloc(sizeof(pthread_mutex_t)); pthread_mutex_init(mutex, NULL); pthread_t p1, p2; pthread_create(&p1, NULL, count_thread, make_args(max, 'A', mutex)); pthread_create(&p2, NULL, count_thread, make_args(max, 'B', mutex)); pthread_join(p1, NULL); pthread_join(p2, NULL); pthread_mutex_destroy(mutex); printf("main: done\n [counter: %d]\n [should: %d]\n", counter, max * 2); return 0; }