首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >线程互斥锁不能正常工作

线程互斥锁不能正常工作
EN

Stack Overflow用户
提问于 2016-01-21 23:01:01
回答 2查看 4.3K关注 0票数 5

我目前正在麻省理工学院的开放课件课程“C中的实用编程”中学习C。在讨论多线程中的竞赛条件时,课堂讲稿中包含了一个具有竞赛条件的程序的示例,以及如何使用互斥对象来解决这个问题。这些代码在linux系统上按预期工作,但在OS上不起作用。

代码语言:javascript
复制
#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台计算机/VM上编译这个程序:一台运行OSX10.10(第一台运行10.11),一台使用Kali Linux (基本上是Debian Jessie ),另一台运行Ubuntu。两次OS运行都显示了与描述相同的奇怪行为。然而,这两个Linux系统都像预期的那样产生了完美的400000000。

所以我的问题是,为什么互斥不能像预期的那样在OS上工作呢?

EN

回答 2

Stack Overflow用户

发布于 2016-01-21 23:11:50

你没有初始化互斥对象。你可以这样做:

代码语言:javascript
复制
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

或者在main函数中,执行以下操作:

代码语言:javascript
复制
if ( pthread_mutex_init( &mutex, NULL) != 0 )
    printf( "mutex init failed\n" );
票数 9
EN

Stack Overflow用户

发布于 2016-01-22 00:01:35

它之所以适用于linux,是因为在linux下:

代码语言:javascript
复制
#define PTHREAD_MUTEX_INITIALIZER { { 0, 0, 0, 0, 0, { 0 } } }

因为互斥变量是..bss变量,所以它是如何初始化互斥的。

在MacOSX下,它是其他一些神奇的价值:

代码语言:javascript
复制
#define PTHREAD_MUTEX_INITIALIZER {_PTHREAD_MUTEX_SIG_init, {0}}
#define _PTHREAD_MUTEX_SIG_init     0x32AAABA7

因此,它确实需要初始化才能正常工作。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34936019

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档