0

我试图理解为什么 pthread_mutex_init 需要在 pthread_mutex_lock 之后调用。

我编写了一个小程序,显示在 pthread_mutex_init 之前调用 pthread_mutex_lock 时行为很奇怪(见下文),但我不明白为什么会这样。

#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;
}

在 main 开头调用 pthread_mutex_init 时,这就是预期的输出。

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

当 pthread_mutex_init 被注释掉时,每次程序运行时输出都会改变。

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

为什么会这样?

4

2 回答 2

0

pthread_mutex_t变量是一个结构。如果您声明一个变量而没有为其分配初始值,则该变量将包含未定义的垃圾。由于该变量未定义,因此基于此变量的所有行为也将未定义。

Consider following scenario: if you skipped initialization of int count variable, the program would print some random numbers instead of numbers from range (1,2,3,4,5).

Difference between int count and pthread_mutex_t mutex is that the latter is defined as a structure, and to initialize structure you have to initialize it's fields. To do that, you use pthread_mutex_init().

tldr: using variables with undefined value causes undefined behavior.

于 2021-06-17T10:22:49.010 回答
0

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;
于 2021-06-18T01:47:24.857 回答