使用pthread_cond_t和pthread_mutex_t

时间:2015-07-07 09:17:06

标签: c multithreading pthreads race-condition

我测试了在多线程代码中打印偶数/奇数的两个非常简单的例子,一个使用pthread_cond_t而另一个没有。

void *even(void *arg)
{

    while(count < MAX) 
    {   
        pthread_mutex_lock(&mutex);
        if(count % 2 == 0)
            printf("%d ", count++);
        pthread_mutex_unlock(&mutex);
    }   
    pthread_exit(0);
}   

void *odd(void *arg)
{

    while(count < MAX)
    {
        pthread_mutex_lock(&mutex);
        if(count % 2 == 1) 
            printf("%d ", count++);
        pthread_mutex_unlock(&mutex);
    }   
    pthread_exit(0);
}  
void *even(void *arg)
{   
    while(count < MAX) {
        pthread_mutex_lock(&mutex);
        while(count % 2 != 0) {
            pthread_cond_wait(&cond, &mutex);
        }   
        printf("%d ", count++);
        pthread_mutex_unlock(&mutex);
        pthread_cond_signal(&cond);
    }
    pthread_exit(0);
}

void *odd(void *arg)
{   
    while(count < MAX) {
        pthread_mutex_lock(&mutex);
        while(count % 2 != 1) {
            pthread_cond_wait(&cond, &mutex);
        }
        printf("%d ", count++);
        pthread_mutex_unlock(&mutex);
        pthread_cond_signal(&cond);
    }
    pthread_exit(0);
}

以上两个代码表现不同。 第一个代码输出:

0 1 2 3 4 5 6 7 8 9 10
0 1 2 3 4 5 6 7 8 9 10
0 1 2 3 4 5 6 7 8 9 10
0 1 2 3 4 5 6 7 8 9  
0 1 2 3 4 5 6 7 8 9 10 
0 1 2 3 4 5 6 7 8 9 10 
0 1 2 3 4 5 6 7 8 9  

第二代码输出:

0 1 2 3 4 5 6 7 8 9 10 
0 1 2 3 4 5 6 7 8 9 10 
0 1 2 3 4 5 6 7 8 9 10 
0 1 2 3 4 5 6 7 8 9 10 

第一个代码的输出不一致的原因可能是:

在偶数线程中的以下调用之间:假设count == 8

pthread_mutex_unlock(&mutex);
..... --> here, the odd thread increments the count by one before this thread could check the the following while condition 
while(count < MAX)

偶尔会错过10个。

但是对于使用pthread_cond_wait()的代码,没有这样的不一致,尽管可以为它做同样的参数: 在这些调用之间甚至是线程:假设count == 8

pthread_cond_signal(&cond);// mutex is already unlocked before condition is signaled.
.... --> here, the odd thread can increment the count to 10 before the even thread could check the while condition
while(count < MAX)

但实际上,第二代码永远不会发生这种情况,所以不知何故,pthread_cond_wait()代码会处理这种不一致的问题,但我似乎不清楚它是怎么回事?

在pthread_cond_wait()中幕后还有其他什么可以帮助吗?

由于

1 个答案:

答案 0 :(得分:2)

两个代码段都有同样的问题。两个版本都有竞争条件。您正在关键部分之外阅读count,其他线程可能会在此期间修改count。 您恰好注意到没有条件变量的版本。

不是为循环条件读取count,而是可以使用每个线程的本地标志,并在循环内更改它以打破循环。

类似的东西:

void *even(void *arg)
{
int flag = 1;

    while(flag) {
        pthread_mutex_lock(&mutex);
        while(count % 2 != 0) {
            pthread_cond_wait(&cond, &mutex);
        }
        printf("%d ", count++);
        if (count >MAX) flag = 0;
        pthread_mutex_unlock(&mutex);
        pthread_cond_signal(&cond);
    }
    pthread_exit(0);
}

void *odd(void *arg)
{
int flag = 1;

    while(flag) {
        pthread_mutex_lock(&mutex);
        while(count % 2 != 1) {
            pthread_cond_wait(&cond, &mutex);
        }
        printf("%d ", count++);
        if (count >MAX) flag = 0;
        pthread_mutex_unlock(&mutex);
        pthread_cond_signal(&cond);
    }
    pthread_exit(0);
}