为什么我需要在 C 中初始化 pthread mutex?
Why do I need to initialize pthread mutex in C?
我想了解为什么 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
为什么会这样?
pthread_mutex_t
变量是一个结构体。如果你声明一个变量而不给它赋初值,这个变量将包含未定义的垃圾。由于该变量是未定义的,所有基于该变量的行为也将是未定义的。
考虑以下场景:如果您跳过 int count
变量的初始化,程序将打印一些随机数而不是 (1,2,3,4,5)
.
范围内的数字
int count
和pthread_mutex_t mutex
之间的区别在于后者被定义为一个结构,并且要初始化结构你必须初始化它的字段。为此,您可以使用 pthread_mutex_init()
.
tldr:使用具有未定义值的变量会导致未定义的行为。
I am trying to understand why pthread_mutex_init needs to be called after 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;
我想了解为什么 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
为什么会这样?
pthread_mutex_t
变量是一个结构体。如果你声明一个变量而不给它赋初值,这个变量将包含未定义的垃圾。由于该变量是未定义的,所有基于该变量的行为也将是未定义的。
考虑以下场景:如果您跳过 int count
变量的初始化,程序将打印一些随机数而不是 (1,2,3,4,5)
.
int count
和pthread_mutex_t mutex
之间的区别在于后者被定义为一个结构,并且要初始化结构你必须初始化它的字段。为此,您可以使用 pthread_mutex_init()
.
tldr:使用具有未定义值的变量会导致未定义的行为。
I am trying to understand why pthread_mutex_init needs to be called after 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;