cpthreadsboost-mutex

Why do I need to initialize pthread mutex in C?


I am trying to understand why pthread_mutex_init needs to be called after pthread_mutex_lock.

I wrote a small program that shows that the behavior is weird when pthread_mutex_lock is called before pthread_mutex_init (see below) but I do not understand why this is the case.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

pthread_mutex_t mutex;
int count = 0;
void* do_stuff(int* param) {
  int* count = (int*) param;
  pthread_mutex_lock(&mutex);
  (*count)++;
  printf("Count was just incremented to: %d\n", *count);

  pthread_mutex_unlock(&mutex);

  return NULL;
}
int main(void) {
  //pthread_mutex_init(&mutex, NULL); **TRYING TO FIGURE OUT WHY THIS IS NEEDED**
  int * x;
  *x = 10;
  pthread_t *p_tids = malloc(sizeof(pthread_t)*5);
  for (int i = 0; i < 5; i++) {
    printf("this is i %d\n", i);
    pthread_create( p_tids + i, NULL, (void*)do_stuff, (void*)&count );
  }  
  for (int j =0; j < 5; j++) {
    pthread_join( p_tids[j], NULL );
  }  
  pthread_mutex_destroy(&mutex);

  return 0;
}

When pthread_mutex_init is called at the beginning of main this is the output as expected.

Count was just incremented to: 1
Count was just incremented to: 2
Count was just incremented to: 3
Count was just incremented to: 4
Count was just incremented to: 5

When pthread_mutex_init is commented out the output changes each time the program is run.

Ex 1:
Count was just incremented to: 1
Count was just incremented to: 5
Count was just incremented to: 2
Count was just incremented to: 3
Count was just incremented to: 4

Ex 2:
Count was just incremented to: 2
Count was just incremented to: 1
Count was just incremented to: 3
Count was just incremented to: 4
Count was just incremented to: 5

Ex 3:
Count was just incremented to: 1
Count was just incremented to: 2
Count was just incremented to: 1
Count was just incremented to: 3
Count was just incremented to: 4

Why is this the case?


Solution

  • I am trying to understand why pthread_mutex_init needs to be called after pthread_mutex_lock.

    I presume you mean you want to know why pthread_mutex_init needs to be called before pthread_mutex_lock. That's simple: you need to ensure that the mutex is in a valid, known state before you use it. POSIX allows for the possibility that although default initialization of an object of type pthread_mutex_t yields a well-defined state, that state is not a valid, unlocked one at the pthreads level. Your experiment seems to demonstrate that your pthreads implementation in fact realizes that possibility.

    Note well, though, that you don't necessarily need to use pthread_mutex_init() to achieve that valid starting state. Since you seem to be satisfied with a mutex with default attributes, you could instead use the initializer macro:

    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;