gpt4 book ai didi

c - 在乒乓测试中使用 pthread 条件变量

转载 作者:太空宇宙 更新时间:2023-11-03 23:23:49 24 4
gpt4 key购买 nike

我在乒乓测试中使用 pthread 条件变量作为同步原语。乒乓测试由两个线程交替执行。每个线程写入另一个线程的内存并使用信号将其唤醒,然后在自己的内存上等待并休眠,稍后将由另一个线程写入。这是我的第一个版本。当我循环这个乒乓测试10,000次时它工作正常,但是当我改为100,000次时,它偶尔会挂起。 N=1,000,000 肯定会挂。我尝试调试并打印出每个循环的循环号,但是在我添加打印语句后程序再也没有挂起,这很烦人。这是乒乓测试代码:

for(i=0; i<N+1; i++)
{
if(i==N)
{
pthread_cond_signal(&cond[dest]);
break;
}
pthread_mutex_lock(&mutex[dest]);
messages[dest]=my_rank;
pthread_cond_signal(&cond[dest]);
pthread_mutex_unlock(&mutex[dest]);
pthread_mutex_lock(&mutex[my_rank]);
while(pthread_cond_wait(&cond[my_rank], &mutex[my_rank]) && messages[my_rank]!=dest);
messages[my_rank]=my_rank;
pthread_mutex_unlock(&mutex[my_rank]);
printf("rank=%ld i=%ld messages[%ld]=%ld\n", my_rank, i, my_rank, messages[my_rank]);
}

然后我尝试了第二个版本,即使我将 N 设置为 1,000,000,它也不会挂起。我从两个互斥量更改为一个由两个条件变量共享的互斥量。我不确定这是否是正确的方法,但这个方法再也不会挂起。这是代码:

for(i=0; i<N+1; i++)
{
if(i==N)
{
pthread_cond_signal(&cond[dest]);
break;
}
pthread_mutex_lock(&mutex[0]);
messages[dest]=my_rank;
pthread_cond_signal(&cond[dest]);
while(pthread_cond_wait(&cond[my_rank], &mutex[0]) && messages[my_rank]!=dest);
messages[my_rank]=my_rank;
pthread_mutex_unlock(&mutex[0]);
}

我很困惑。有人可以帮我解释为什么第一个版本挂起而第二个版本没有挂起吗?两个条件变量共享一个互斥锁是否正确?

谢谢。


谢谢大家,尤其是caf。这是我的最终代码,无需挂起即可运行。

for(i=0; i<N+1; i++)
{
pthread_mutex_lock(&mutex[dest]);
messages[dest]=my_rank;
pthread_cond_signal(&cond[dest]);
pthread_mutex_unlock(&mutex[dest]);
if(i!=N)
{
pthread_mutex_lock(&mutex[my_rank]);
while(messages[my_rank]!=dest)
pthread_cond_wait(&cond[my_rank], &mutex[my_rank]);
messages[my_rank]=my_rank;
pthread_mutex_unlock(&mutex[my_rank]);
}
}

最佳答案

问题出在这一行:

while (pthread_cond_wait(&cond[my_rank], &mutex[my_rank]) && messages[my_rank]!=dest);

如果在解锁 mutex[dest] 之后和锁定 mutex[my_rank] 之前调度“dest”线程,它将设置 messages[my_rank ] 并向条件变量发出信号,此线程调用 pthread_cond_wait() 之前,因此此线程将永远等待。

解决这个问题非常简单:测试 messages[my_rank] before 等待条件变量。您也不希望 && 在这里,因为只要 messages[my_rank] != dest 为真,您总是希望继续循环 - 您不想中断在 pthread_cond_wait() 的第一个非零返回时输出。所以如果你想忽略来自 pthread_cond_wait() 的错误(就像你原来的那样,如果你没有使用错误检查或健壮的互斥锁,这是完全没问题的,因为那些是唯一的时间 pthread_cond_wait() 允许失败),使用:

while (messages[my_rank] != dest)
pthread_cond_wait(&cond[my_rank], &mutex[my_rank]);

您的替代版本没有此错误的原因是因为在向 dest 线程发送信号和等待条件变量之间一直持有锁,因此 dest 在我们确定等待之前,线程没有机会运行。


关于你的补充问题:

Is it correct for two condition variable sharing a single mutex?

是的,这是允许的,但反过来是不允许的(您不能使用不同的互斥量,让两个线程同时等待同一个条件变量)。

关于c - 在乒乓测试中使用 pthread 条件变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31963818/

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