C 条件变量和互斥锁解锁
代码:C 条件变量和互斥锁解锁,c,pthreads,mutex,condition-variable,C,Pthreads,Mutex,Condition Variable,代码: void*inc_func(void*arg) { pthread_mutex_lock(&mutex); pthread_cond_信号(&count_threshold_cv); 睡眠(1); pthread_mutex_unlock(&mutex); } void*watch(void*arg) { pthread_mutex_lock(&mutex); pthread_cond_wait(&count_threshold_cv,&mutex); 睡眠(1); pthread_mu
void*inc_func(void*arg)
{
pthread_mutex_lock(&mutex);
pthread_cond_信号(&count_threshold_cv);
睡眠(1);
pthread_mutex_unlock(&mutex);
}
void*watch(void*arg)
{
pthread_mutex_lock(&mutex);
pthread_cond_wait(&count_threshold_cv,&mutex);
睡眠(1);
pthread_mutex_unlock(&mutex);
}
int main()
{
pthread_t id[2];
pthread_创建(&id[0],NULL,watch,NULL);
pthread_create(&id[1],NULL,inc_func,NULL);
int i;
对于(i=0;i
pthread\u mutex\u lock()
pthread\u cond\u wait()
在开始等待时解锁互斥体,并在返回前锁定。如果相关互斥体仍处于锁定状态,则返回可能会延迟。然后返回将延迟,直到互斥体解锁
将以上内容放在一起并将其应用到您展示的代码中,您会看到每个线程函数都以锁定和解锁(等等)开始,所以一切都很好
参考示例代码:pthread\u cond\u wait()
在调用pthread\u mutex\u unlock()
时返回
若要成功处理示例代码描述的场景,需要考虑两个特殊情况
信号先发后发的情况
所谓的情况,即pthread\u cond\u wait()
在未发出信号的情况下返回
为了处理这两种情况,每个条件都应该有一个watch变量
void *inc_func(void *arg)
{
pthread_mutex_lock(&mutex);
pthread_cond_signal(&count_threshold_cv);
sleep(1);
pthread_mutex_unlock(&mutex);
}
void *watch(void *arg)
{
pthread_mutex_lock(&mutex);
pthread_cond_wait(&count_threshold_cv,&mutex);
sleep(1);
pthread_mutex_unlock(&mutex);
}
int main()
{
pthread_t id[2];
pthread_create(&id[0],NULL,watch,NULL);
pthread_create(&id[1],NULL,inc_func,NULL);
int i;
for(i=0;i<2;i++)
pthread_join(id[i],NULL);
}
pthread\u mutex\u t mutex=。。。
pthread_cond_t count_threshold_cv=。。。
int信号=0;
void*inc_func(void*arg)
{
pthread_mutex_lock(&mutex);
pthread_cond_信号(&count_threshold_cv);
信号=1;
pthread_mutex_unlock(&mutex);
}
void*watch(void*arg)
{
pthread_mutex_lock(&mutex);
而(0==信号)
{
pthread_cond_wait(&count_threshold_cv,&mutex);
}
pthread_mutex_unlock(&mutex);
}
内部主(空)
{
pthread_t id[2];
pthread_创建(&id[0],NULL,watch,NULL);
pthread_create(&id[1],NULL,inc_func,NULL);
int i;
对于(i=0;i
watch
首先运行并锁定(而inc_func
等待)
watch
使用pthread\u cond\u wait
打开互斥文本并根据
这些函数以原子方式释放互斥,并导致调用线程
在条件变量cond上阻塞
这允许以下操作
inc_func
获取互斥锁,然后发出信号(此时互斥锁尚未释放)
inc_func
释放互斥锁
- 由于已释放互斥锁且互斥锁已解锁,
watch
的执行将按照以下步骤继续锁定互斥锁:
成功返回后,互斥锁已被锁定,并由调用线程拥有
- 接下来是互斥的合法释放
您没有考虑的情况是,如果代码< CixFunc < /C> >代码首先执行而不切换到<代码> WHOR> <代码> < /P>
inc_func
锁定互斥锁
inc_func
发出信号,但没有人需要发出信号,这是正常的
inc_func
解锁互斥锁
监视
锁定互斥锁
- 然后等待条件变量,但没有人发出信号,因此它将永远等待
这个问题可能是重复的。在展示一些示例代码时已经回答了这个问题,这肯定会有助于避免误解您。我对这个问题进行了更好的重新表述think@InQusitive:您错误地假设pthread\u cond\u wait()
由于pthread\u cond\u signal()而返回
已被调用。情况并非如此。每个定义不能有两个线程持有相同的互斥体。这就是它们的用途。pthread\u mutex\u lock()
如果在已锁定的互斥锁上调用,将只阻塞,而不会返回@InQusitive@InQusitive:您的真实代码是否初始化了它使用的互斥体?您的真实代码是否检查每个pthread_*()
调用函数,测试它是否可能失败?是的,无论如何,我对互斥条件的理解是错误的。现在很清楚了。:)请在答案中添加第二条注释。
pthread_mutex_t mutex = ...
pthread_cond_t count_threshold_cv = ...
int signalled = 0;
void *inc_func(void *arg)
{
pthread_mutex_lock(&mutex);
pthread_cond_signal(&count_threshold_cv);
signalled = 1;
pthread_mutex_unlock(&mutex);
}
void *watch(void *arg)
{
pthread_mutex_lock(&mutex);
while (0 == signalled)
{
pthread_cond_wait(&count_threshold_cv,&mutex);
}
pthread_mutex_unlock(&mutex);
}
int main(void)
{
pthread_t id[2];
pthread_create(&id[0],NULL,watch,NULL);
pthread_create(&id[1],NULL,inc_func,NULL);
int i;
for(i=0;i<2;i++)
pthread_join(id[i],NULL);
}