gpt4 book ai didi

c - 使用 pthread_cond_t 和 pthread_mutex_t

转载 作者:太空宇宙 更新时间:2023-11-04 08:24:34 25 4
gpt4 key购买 nike

我测试了两个非常简单的在多线程代码中打印偶数/奇数的示例,一个使用 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

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

在偶数线程中的以下调用之间:假设计数 == 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() 的幕后是否还有其他事情可以提供帮助?

谢谢

最佳答案

两个代码片段都有同样的问题。两个版本都有竞争条件。您正在关键部分之外读取 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);
}

关于c - 使用 pthread_cond_t 和 pthread_mutex_t,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31264498/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com