简体   繁体   English

使用pthread_cond_t和pthread_mutex_t

[英]using pthread_cond_t and pthread_mutex_t

I tested out two very simple examples of printing even/odd numbers in multithreaded code, one using pthread_cond_t and the other not. 我测试了两个非常简单的示例,这些示例在多线程代码中打印偶数/奇数,一个使用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);
}

The above two codes behave differently. 上面两个代码的行为不同。 1st code output: 第一个代码输出:

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  

2nd code output: 第二代码输出:

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 

The reason for the inconsistent output for 1st code could be that: 第一个代码的输出不一致的原因可能是:

in between the following calls in even thread: suppose count == 8 在偶数线程中的以下调用之间:假定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)

so 10 is missed occasionally. 所以偶尔会错过10个。

But for the code using pthread_cond_wait(), there is no such inconsistency, although, the same argument can be made for it aswell: in between these calls in even thread:suppose count == 8 但是对于使用pthread_cond_wait()的代码,没有这种不一致,但是,也可以为其设置相同的参数:在这些调用之间,甚至在线程中:suppose 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)

But in practice,this never happend for 2nd code, so somehow, pthread_cond_wait() code takes care of such inconsistency, but it seems unclear to me how? 但是实际上,这在第二代码中从来没有发生过,所以以某种方式,pthread_cond_wait()代码可以解决这种不一致的问题,但是我不清楚如何处理?

Is there anything else going on behind the scenes in pthread_cond_wait() that helps out? pthread_cond_wait()幕后是否还有其他有用的方法?

Thanks 谢谢

Both code snippets has the same problem. 这两个代码段都有相同的问题。 Both versions have race condition . 两种版本都有比赛条件 You are reading count outside the critical section and other thread might modify count in the meantime. 您正在阅读count的关键部分和其他线程之外可能会修改count在其间。 You just happen to notice in the version without conditional variable. 您只是偶然发现版本中没有条件变量。

Instead of reading count for loop condition, you can use flag that's local to each thread and change it inside the loop for breaking the loop. 您可以使用每个线程本地的标志并在循环内部更改它以破坏循环,而不必读取循环条件的count

Something like: 就像是:

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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM