使用互斥

问题描述:

我写了一个简单的并行线程代码使用互斥

#include <pthread.h> 
#include <stdio.h> 
#include <math.h> 

#define ITERATIONS 500 

// A shared mutex 
pthread_mutex_t mutex; 
int target; 

void* opponent(void *arg) 
{ 
    int i; 
    printf("opp, before for target=%d\n", target); 
    pthread_mutex_lock(&mutex); 
    for(i = 0; i < ITERATIONS; ++i) 
    { 
    target++; 
    } 
    pthread_mutex_unlock(&mutex); 
    printf("opp, after for target=%d\n", target); 

    return NULL; 
} 

int main(int argc, char **argv) 
{ 
    pthread_t other; 

    target = 5; 

    // Initialize the mutex 
    if(pthread_mutex_init(&mutex, NULL)) 
    { 
    printf("Unable to initialize a mutex\n"); 
    return -1; 
    } 

    if(pthread_create(&other, NULL, &opponent, NULL)) 
    { 
    printf("Unable to spawn thread\n"); 
    return -1; 
    } 

    int i; 
    printf("main, before for target=%d\n", target); 
    pthread_mutex_lock(&mutex); 
    for(i = 0; i < ITERATIONS; ++i) 
    { 
    target--; 
    } 
    pthread_mutex_unlock(&mutex); 
    printf("main, after for target=%d\n", target); 

    if(pthread_join(other, NULL)) 
    { 
    printf("Could not join thread\n"); 
    return -1; 
    } 

    // Clean up the mutex 
    pthread_mutex_destroy(&mutex); 

    printf("Result: %d\n", target); 

    return 0; 
} 

然后我用这个命令编译

gcc -pedantic -Wall -o theaded_program pth.c -lpthread 

不过,我每次运行程序时,我得到不同的结果!

$ ./theaded_program 
main, before for target=5 
main, after for target=-495 
opp, before for target=5 
opp, after for target=5 
Result: 5 

$ ./theaded_program 
main, before for target=5 
opp, before for target=5 
opp, after for target=5 
main, after for target=-495 
Result: 5 

当该互斥锁定他们正在访问target不被执行的printf()语句和:

printf("opp, before for target=%d\n", target); 
pthread_mutex_lock(&mutex); 

这意味着一个线程潜在地改变的target的值,而另一个线程试图读取它(在printf())。移动时互斥锁定将要执行的printf()声明:

pthread_mutex_lock(&mutex); 
printf("opp, before for target=%d\n", target); 
/* snip */ 
printf("opp, after for target=%d\n", target); 
pthread_mutex_unlock(&mutex); 

这将防止target由一个线程读取,并通过另一个同时修改。但是,不能保证哪个线程会首先获取互斥锁。

+0

然后解决方案是什么? – mahmood 2013-04-04 12:51:57

+0

@mahmood,建议更新答案。 – hmjd 2013-04-04 12:55:27

+0

谢谢你是对的 – mahmood 2013-04-04 12:57:48

这一结果符合市场预期,你的代码保证了主,对手不会在同一时间做

for(i = 0; i < ITERATIONS; ++i) 
{ 
    target--; //or ++ for the opponent 
} 

printf不受任何互斥体保护。为避免这种情况,在互斥锁/解锁中插入printf s