pthread互斥锁无法正常工作

时间:2016-01-21 23:01:01

标签: c multithreading pthreads mutex

我目前正在从麻省理工学院开放课件中学习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上没有按预期工作?

2 个答案:

答案 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

因此必须初始化才能使其正常工作。