// Working version of threaded picalc. Uses a mutex to lock the global // variable total_hits so that one thread accesses it at a time. This // version is inefficient due to the busy waiting and contention // associated with mutex locking. #include #include #include // Global variables shared by all threads int total_hits=0; int points_per_thread = -1; pthread_mutex_t lock; void *compute_pi(void *arg){ long thread_id = (long) arg; unsigned int rstate = 123456789 * thread_id; // give each thread its own starting point for (int i = 0; i < points_per_thread; i++) { double x = ((double) rand_r(&rstate)) / ((double) RAND_MAX); double y = ((double) rand_r(&rstate)) / ((double) RAND_MAX); if (x*x + y*y <= 1.0){ pthread_mutex_lock(&lock); // lock global variable total_hits++; // update pthread_mutex_unlock(&lock); // unlock global variable } } return NULL; } int main(int argc, char **argv) { if(argc < 2){ printf("usage: %s [num_threads]\n",argv[0]); printf(" num_samples: int, how many sample points to try, higher gets closer to pi\n"); printf(" num_threads: int, number of threads to use for the computation, default 4\n"); return -1; } int npoints = atoi(argv[1]); // number of samples int num_threads = argc>2 ? atoi(argv[2]) : 4; // number of threads points_per_thread = npoints / num_threads; // init global variables pthread_mutex_init(&lock, NULL); // create a lock pthread_t threads[num_threads]; // track each thread for(long p=0; p