我知道我的问题有很多例子。但是,我想理解为什么我编写的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;
}
}
非常感谢。
答案 0 :(得分:2)
在第一个例子中,可能会发生以下一些变化:
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);
答案 1 :(得分:0)
在第一个示例中,在even()
中,如果count为奇数,则pthread_cond_signal
odd()
如果count
为偶数则运行count
odd()
。 even()
将递增,并且互斥量会下降。此时even()
可能会在pthread_cond_wait()
到达odd()
之前运行并发出even()
信号。现在count
永远不会再发出even()
信号(因为pthread_cond_wait()
现在是偶数),count
' s {{1}}永远不会退出。
但是你的两个例子都是错误的。您是(上一个完整行)在保护它的互斥锁之外读取{{1}}。
答案 2 :(得分:-1)
#include <stdio.h>
#include <pthread.h>
#include<iostream>
void *odd(void* data);
void *even(void* data);
static int count=0;
pthread_mutex_t mutex;
pthread_cond_t cond;
int main()
{
pthread_t thread1,thread2;
pthread_create(&thread1,NULL,&even,0);
pthread_create(&thread2,NULL,&odd,0);
pthread_join(thread1,NULL);
pthread_join(thread2,NULL);
return 0;
}
void *even(void* data)
{
pthread_mutex_lock(&mutex);
while(count< 10)
{
while(count%2!=0)
{
pthread_cond_wait(&cond,&mutex);
}
std::cout<<count;
count++;
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond);
}
pthread_exit(0);
}
void *odd(void* data)
{
pthread_mutex_lock(&mutex);
while(count<10)
{
while(count%2!=1)
{
pthread_cond_wait(&cond,&mutex);
}
std::cout<<count;
count++;
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond);
}
pthread_exit(0);
}