首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >条件变量与mutex_unlock

条件变量与mutex_unlock
EN

Stack Overflow用户
提问于 2015-03-28 17:54:11
回答 2查看 299关注 0票数 0

代码:

代码语言:javascript
复制
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。我的理解错了吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-03-28 18:10:33

  • 如果要锁定的互斥对象已经锁定,则pthread_mutex_lock()将阻塞。如果互斥锁被解锁它就会返回。
  • pthread_cond_wait()在开始等待时解锁互斥锁,锁在返回之前。如果所讨论的互斥对象仍然被锁定,返回可能会延迟。返回将是延迟,直到互斥锁被打开。

将上述内容组合在一起,并将其应用到您所展示的代码中,可以看到每个线程函数都从锁定开始,然后是解锁(以此类推),所以一切都很好。

参考示例代码:pthread_cond_wait()inc_func()调用pthread_mutex_unlock()时返回。

要成功地处理示例代码所描述的场景,需要考虑两种特殊情况

  1. 信号首先出现的情况
  2. 所谓的情况是,pthread_cond_wait()返回时没有发出信号。

要处理这两种情况,每个条件都应该有一个watch变量。

代码语言:javascript
复制
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);
}  
票数 1
EN

Stack Overflow用户

发布于 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锁定互斥对象
  • 然后等待条件变量,但是没有人发出信号,所以它将永远等待。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29320565

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档