2011-06-30 43 views
3

我正在Linux中使用pthread实现手动重置事件,这与Windows中的WaitForSingleEvent类似。我发现这个职位pthread_cond_wait和pthread_mutex_unlock是否冲突?

pthread-like windows manual-reset event

,并按照它,但是有没有让我困惑的事:

void mrevent_wait(struct mrevent *ev) { 
    pthread_mutex_lock(&ev->mutex); 
    while (!ev->triggered) 
     pthread_cond_wait(&ev->cond, &ev->mutex); 
    pthread_mutex_unlock(&ev->mutex); 
} 
  • 调用pthread_cond_wait: 原子方式释放互斥锁,并导致调用线程基于条件方框变量cond;
  • pthread_mutex_unlock: 尝试解锁指定的互斥锁。如果互斥类型为PTHREAD_MUTEX_NORMAL,则不提供错误检测。如果一个线程试图解锁一个互斥锁,即尚未锁定或解锁的互斥锁,则会导致未定义的行为。

什么我恐慌时调用pthread_cond_wait释放互斥锁,然后可以调用pthread_mutex_unlock来未定义行为(这种事情将推动我疯了,为什么他们不能处理它:-D)

谢谢您。

回答

9

The standard说:

在成功返回时,互斥体 被锁定,并通过 调用线程拥有。

这意味着,返回时,pthread_cond_wait原子锁定关联的互斥锁。

的工作流程是这样的:

  • 您锁定一个互斥体
    • pthread_cond_wait原子块和解锁互斥量(所以其他线程可能会在这里)
    • 当条件到达时,pthread_cond_wait原子回报并锁定互斥锁
  • 您解锁互斥锁

我不认为调用pthread_cond_wait块 和解锁

那是因为你没看过我提供的链接。

这些功能原子方式释放 互斥并导致调用线程基于条件变量COND 块;

+0

总之,在'pthread_cond_wait'之后解锁互斥锁是有效的(并且是必需的)。 – cnicutar

+0

我不认为pthread_cond_wait块和解锁。但是,如果它首先解锁互斥锁,然后尝试锁定互斥锁,那么我认为这可能导致此处出现死锁。顺便说一句,任何人都知道为什么我们必须将pthread_cond_wait放入while循环中?我可以只使用if语句吗?谢谢! – longbkit

+1

@longbkit看到我编辑的答案。你的第二个问题在这里回答:http://stackoverflow.com/questions/6505567/about-pthread-cond-signal-and-pthread-cond-wait/6507488#6507488 – cnicutar