[英]Unexpected output in event ordering using pthread conditional wait
我编写了以下代码,以了解使用pthreads和互斥锁进行事件排序的知识。 main函数创建两个与函数func1和func2关联的线程。 函数func1检查count的值,并有条件地等待func2发出信号。 函数func2递增计数 ,当计数达到50000时,它将发出信号func1 。 然后func1打印那时的计数值 (或应该是50000)。
但是在实际输出中,还将打印50000和其他一些值。 我没有任何理由这样做。 我认为是,当func2发出信号时, func1会在pthread_cond_wait语句之后唤醒并执行,因此它应该只打印50000。请指出我错了,应该进行哪些更改以获取正确的输出?
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
pthread_mutex_t evmutex;
pthread_cond_t evcond;
char a;
int count;
int N = 50000;
void *func1()
{
while(1)
{
pthread_mutex_lock(&evmutex);
if(count < N)
{
pthread_cond_wait(&evcond,&evmutex);
printf("%d\n",count);
count = 0;
}
pthread_mutex_unlock(&evmutex);
}
}
void *func2()
{
while(1)
{
pthread_mutex_lock(&evmutex);
count++;
if(count == N)
{
pthread_cond_signal(&evcond);
}
pthread_mutex_unlock(&evmutex);
}
}
int main ()
{
pthread_t ptd1,ptd2;
pthread_mutex_init(&evmutex,NULL);
pthread_cond_init(&evcond,NULL);
count = 0;
pthread_create(&ptd1,NULL,func1,NULL);
pthread_create(&ptd2,NULL,func2,NULL);
pthread_exit(NULL);
pthread_mutex_destroy(&evmutex);
pthread_cond_destroy(&evcond);
return 0;
}
您尚未与生产者func2()同步,并告诉它等待直到消费者func1()处理了该条件。
没有什么可以阻止生产者发信号通知条件,重新获取互斥量以及再次增加计数器。 pthread_cond_signal并不意味着您的生产者将停止并等待消费者处理。 这意味着生产者可能会在安排您的消费者之前唤醒计数器很多次,然后醒来打印当前数字。
您需要添加另一个条件变量,生产者在将计数器递增到N之后要等待生产者等待,并让消费者在处理完计数器后发出信号。
除此之外,您还需要处理其他答案提到的虚假唤醒。
pthread_cond_wait()
某些实现会遭受虚假唤醒,因此,使用while (cond) { pthread_cond_wait(...); }
while (cond) { pthread_cond_wait(...); }
循环来解决这个问题。
我在这里找到了对该问题的很好的解释,并指出了原因: pthread_cond_wait为什么会有虚假的唤醒?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.