Currently I am learning POSIX threads on Linux. The following example is counting how many 3(int) there are in an integer array, which returns a correct answer on CentOS 6.5 but a wrong one on macOS 10.12.4.
#include <stdlib.h> #include <semaphore.h> #include <pthread.h> #include <unistd.h> #include <stdio.h> #define thread_num 16 #define MB 1024 * 1024 int *array; int length; //array length int count; int t; //number of thread void *count3s_thread(void* id); pthread_mutex_t myMutex;//create a mutex int main() { //initialize mutex if (pthread_mutex_init(&myMutex, NULL) != 0) printf("Mutex init failed!n"); int i; int tid[thread_num]; pthread_t threads[thread_num]; length = 64 * MB; array = malloc(length * 4); //initialize the array //when i is an odd number, array[i] = 4 //when i is an even number, array[i] = 3 for (i = 0; i < length; i++) array[i] = i % 2 ? 4 : 3; for (t = 0; t < thread_num; t++) { count = 0; tid[t]=t; int err = pthread_create(&(threads[t]), NULL, count3s_thread,&(tid[t]) ); if (err) { printf("create thread error!n"); return 0; } } for (t = 1; t < thread_num; t++) pthread_join(threads[t], NULL); printf("Total count= %d n",count); pthread_mutex_destroy(&myMutex); return 0; } void *count3s_thread(void* id) { //printf("id from count3s_thread = %dn", *(int *)id); int length_per_thread = length / thread_num; //length of every thread int start = *(int *)id * length_per_thread; int i; for (i = start; i < start + length_per_thread; i++) { if (array[i] == 3) { pthread_mutex_lock(&myMutex); count++; pthread_mutex_unlock(&myMutex); } } return NULL; }
The answer should be 64 * 1024 * 1024 / 2 = 67,108,864 / 2 = 33,554,432. But the answer on macOS is never right. I compile the code with the following options:
gcc mutex-demo.c -lpthread -o mutex-demo
I have tried solving the problem following this link. However, I still got a wrong answer having initialized pthread mutex. Did I miss something?
PS: I have tried either pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
or pthread_mutex_init( &mutex, NULL)
but the program running on macOS still returns a wrong answer.
Advanced thanks!
Advertisement
Answer
The line count = 0;
before the pthread_create
sets count
to 0
, so you reset the value of count
while the threads increment them. Remove this line. It probably worked on other systems, when the main thread finishes the pthread_create
before the threads starts counting.
I already mentioned it in the comments:
for (t = 1; t < thread_num; t++) pthread_join(threads[t], NULL);
should be
for (t = 0; t < thread_num; t++) // ^ pthread_join(threads[t], NULL);
otherwise you will not wait for the first thread to be done.