我目前正在从麻省理工学院开放课件中学习C语言,在C语言中称为实践编程。在讨论多线程中的竞争条件时,讲义包含一个具有竞争条件的程序示例以及如何使用互斥锁解决它。代码在Linux系统上按预期工作,但在OS X上没有。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t mutex; // Added to fix race condition
unsigned int cnt = 0;
void *count(void *arg) {
int i;
for (i = 0; i < 100000000; i++) {
pthread_mutex_lock(&mutex); // Added to fix race condition
cnt++;
pthread_mutex_unlock(&mutex); // Added to fix race condition
}
return NULL;
}
int main() {
pthread_t tids[4];
int i;
for (i = 0; i < 4; i++)
pthread_create(&tids[i], NULL, count, NULL);
for (i = 0; i < 4; i++)
pthread_join(tids[i], NULL);
pthread_mutex_destroy(&mutex); // Added to fix race condition
printf("cnt = %u\n", cnt);
return 0;
}
在添加互斥锁和相应的函数调用之前,行为与预期一致,为cnt(400000000)生成理想正确响应的可变部分,每次运行时都不同。添加互斥锁之后,这仍然会发生,虽然结果有明显的增加,表明它有一些的预期效果,但远非完美。
我尝试在其他3台计算机/虚拟机上编译这个程序:一个运行OS X 10.10(第一个运行10.11),一个运行Kali Linux(主要是Debian Jessie),另一个运行Ubuntu。两个OS X运行都显示出与所描述的相同的奇怪行为。但是,两个Linux系统都按预期产生了完美的4亿个。
所以我的问题是,为什么互斥锁在OS X上没有按预期工作?
答案 0 :(得分:7)
您没有初始化互斥锁。你可以这样做:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
或在main
函数中,执行以下操作:
if ( pthread_mutex_init( &mutex, NULL) != 0 )
printf( "mutex init failed\n" );
答案 1 :(得分:4)
它与linux一起工作的原因是,因为在linux下:
#define PTHREAD_MUTEX_INITIALIZER { { 0, 0, 0, 0, 0, { 0 } } }
这正是互斥体的初始化方式,因为它是一个.bss变量。
在MacOSX下,它还有一些神奇的价值:
#define PTHREAD_MUTEX_INITIALIZER {_PTHREAD_MUTEX_SIG_init, {0}}
#define _PTHREAD_MUTEX_SIG_init 0x32AAABA7
因此必须初始化才能使其正常工作。