代码:
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);
}现在我们有一个mutex_unlock函数要在每个线程中执行。还有一个锁着的互斥物。为什么这不导致一个undefined behaviour。因为两个线程都试图解锁同一个互斥体,这导致一个线程试图解锁一个已经解锁的互斥体。
编辑:pthread_cond_wait释放mutex供第二个线程使用。现在考虑第二个线程执行pthread_cond_signal,这将导致第一个线程重新获取mutex。现在,我们有两个具有相同mutex锁的线程,因为由于“睡眠”函数,这两个线程都没有执行mutex_unlock。我的理解错了吗?
发布于 2015-03-28 18:10:33
pthread_mutex_lock()将阻塞。如果互斥锁被解锁它就会返回。pthread_cond_wait()在开始等待时解锁互斥锁,锁在返回之前。如果所讨论的互斥对象仍然被锁定,返回可能会延迟。返回将是延迟,直到互斥锁被打开。将上述内容组合在一起,并将其应用到您所展示的代码中,可以看到每个线程函数都从锁定开始,然后是解锁(以此类推),所以一切都很好。
参考示例代码:pthread_cond_wait()在inc_func()调用pthread_mutex_unlock()时返回。
要成功地处理示例代码所描述的场景,需要考虑两种特殊情况
pthread_cond_wait()返回时没有发出信号。要处理这两种情况,每个条件都应该有一个watch变量。
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);
} 发布于 2015-03-28 18:30:46
如果命令确实是
watch首先运行并锁定(而inc_func在等待)watch使用pthread_cond_wait,它按照文档解锁mutext和块这些函数原子释放互斥,导致调用线程在条件变量cond上阻塞;
这允许进行以下操作
inc_func获取互斥对象,然后发出信号(此时互斥锁尚未释放)inc_func释放互斥对象watch的执行恢复了,并且按照文档锁定了互斥锁。在成功返回时,互斥锁已被锁定,并由调用线程拥有。
您没有考虑的情况是,如果inc_func的代码在不切换到watch的情况下首先执行怎么办?
inc_func锁定互斥对象inc_func信号,但没有人被信号,这是可以的。inc_func解锁互斥锁watch锁定互斥对象https://stackoverflow.com/questions/29320565
复制相似问题