Skip to content
Advertisement

pthread mutex does not work correctly on macOS

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.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement