我知道我的问题有很多例子。但是,我想了解为什么我编写的1个程序行不通,而其他程序却不行。
这是我写的。
void * even()
{
while(1)
{
pthread_mutex_lock(&lock);
if(count % 2 == 0)
{
printf("count %d\n",count);
pthread_cond_signal(&cond);
}
else
{
pthread_cond_wait(&cond,&lock);
}
count++;
pthread_mutex_unlock(&lock);
if(count >= 100) return NULL;
}
}
void * odd()
{
while(1)
{
pthread_mutex_lock(&lock);
if(count % 2 == 1)
{
printf("count %d\n",count);
pthread_cond_signal(&cond);
}
else
{
pthread_cond_wait(&cond,&lock);
}
count++;
pthread_mutex_unlock(&lock);
if(count >= 100) return NULL;
}
}
因此,上面的代码有时仅输出0或0和1。但是下面的代码工作正常。
void * even()
{
while(1)
{
pthread_mutex_lock(&lock);
if(count % 2 == 0)
{
printf("count %d\n",count);
count++;
pthread_cond_signal(&cond);
}
else
{
pthread_cond_wait(&cond,&lock);
}
pthread_mutex_unlock(&lock);
if(count >= 100) return NULL;
}
}
void * odd()
{
while(1)
{
pthread_mutex_lock(&lock);
if(count % 2 == 1)
{
printf("count %d\n",count);
count++;
pthread_cond_signal(&cond);
}
else
{
pthread_cond_wait(&cond,&lock);
}
pthread_mutex_unlock(&lock);
if(count >= 100) return NULL;
}
}
非常感谢。
最佳答案
在第一个示例中,可能会发生以下变化:
even()
获取锁even()
显示count
(为0)并发出条件信号(尽管odd()
在even()
释放锁定之前无法唤醒)even()
将count
递增为1 even()
释放锁定,并且odd()
唤醒。 odd()
将count
递增为2 odd()
释放锁定(但尚未发出信号)odd()
获取锁odd()
等待,因为count
是偶数(== 2)...现在,两个线程都在等待,并且两个线程都无法发出信号。 根据哪个线程先发生,事情可能会略有不同,但是两个线程仍然会以与上述类似的方式卡住。
不过,这两个示例都不可靠,因为它们在等待条件时并未考虑到虚假唤醒。通常,如果不满足所需的唤醒条件,则应使用循环重试等待,并始终保持锁定状态,这样就不会丢失信号:
pthread_mutex_lock(&lock);
/* ...stuff... */
/* Use a loop to restart the wait if it was interrupted early */
while(count % 2 != 0)
pthread_cond_wait(&cond,&lock);
/* ...stuff... */
pthread_mutex_unlock(&lock);