【问题标题】:Why do I need to initialize pthread mutex in C?为什么我需要在 C 中初始化 pthread 互斥锁?
【发布时间】:2021-09-01 21:11:38
【问题描述】:

我试图理解为什么 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;
}

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

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

为什么会这样?

【问题讨论】:

    标签: c pthreads boost-mutex


    【解决方案1】:

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

    我猜你的意思是你想知道为什么pthread_mutex_init 需要被称为之前 pthread_mutex_lock。这很简单:在使用互斥体之前,您需要确保它处于有效的已知状态。 POSIX 允许以下可能性:尽管pthread_mutex_t 类型的对象的默认初始化会产生一个定义明确的 状态,但该状态在 pthreads 级别不是有效的、未锁定的状态。您的实验似乎表明您的 pthreads 实现实际上实现了这种可能性。

    请注意,您不一定需要使用pthread_mutex_init() 来实现有效的起始状态。由于您似乎对具有默认属性的互斥锁感到满意,因此您可以改用初始化器宏:

    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    

    【讨论】:

      【解决方案2】:

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

      考虑以下场景:如果您跳过了int count 变量的初始化,程序将打印一些随机数而不是(1,2,3,4,5) 范围内的数字。

      int countpthread_mutex_t mutex 之间的区别在于后者被定义为一个结构,并且要初始化结构,您必须初始化它的字段。为此,您可以使用pthread_mutex_init()

      tldr:使用具有未定义值的变量会导致未定义的行为。

      【讨论】:

      • 巴尔德达什。所有具有静态存储持续时间的对象都有明确定义的初始值,无论是否声明了初始化器。这包括在文件范围内声明的所有对象,例如 OP 的互斥锁。结构也不例外。
      猜你喜欢
      • 2020-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-11
      • 1970-01-01
      • 2011-02-15
      相关资源
      最近更新 更多