POSIX条件变量和互斥体“竞争”

时间:2019-09-27 17:25:14

标签: c++ multithreading posix mutex condition-variable

当线程等待条件变量时,(原子地)释放(解锁)关联的互斥锁。当(通过不同的线程)用信号通知该条件变量时,将唤醒一个(用于信号)或所有(用于广播)等待线程,从而自动重新获取(锁定)互斥锁。

如果一个或多个其他线程正在等待获取(锁定)相同的互斥锁,而不是在相同的条件下等待,将会发生什么?在其他线程可以获取(锁定)互斥锁之前,等待条件变量的线程是否保证被唤醒(从而获取互斥锁),还是其他线程可以获取(锁定)互斥锁?在线程等待条件变量之前?

[注意:为清楚起见,下面的示例已简化。 Thread_B并不会真正启动Thread_C,但要保证Thread_C不会运行,直到Thread_B获得互斥量之后-Thread_A等待条件变量后,它不会与Thread_B竞争该互斥量。

线程_A:

pthread_mutex_lock(&myMutex);
while (!someState) {
    pthread_cond_wait(&myCondVar,&myMutex);
}
// do something
pthread_mutex_unlock(&myMutex);

Thread_B:

pthread_mutex_lock(&myMutex);
// do other things
someState = true;
// start Thread_C here
pthread_cond_signal(&myCondVar);
pthread_mutex_unlock(&myMutex);

Thread_C:

pthread_mutex_lock(&myMutex);
// can I reach this point after Thread_B releases the mutex,
// but before Thread_A re-acquires it after being signaled?

// do things that may interfere with Thread_A...
pthread_mutex_unlock(&myMutex);

编辑:选择以下可接受的答案是因为它清楚表明读者是否同意给定的解释,并且有足够的歧义,唯一安全的假设是被访者。请注意,其他精通C ++标准语言的人可能会发现文本完全明确...我不在那个小组中。

1 个答案:

答案 0 :(得分:3)

pthread_cond_[timed]wait()中已经阻塞的任何其他试图获取相同互斥锁的线程相比,从pthread_mutex_lock()唤醒时获取互斥锁没有什么特别的。

Per the POSIX 7 pthread_cond_signal() documentation(正在炸雷):

  

如果在一个条件变量上阻塞了多个线程,则调度策略将确定解除阻塞线程的顺序。当每个因pthread_cond_broadcast()pthread_cond_signal()而被解除阻塞的线程从其对pthread_cond_wait()pthread_cond_timedwait()的调用返回时,该线程应拥有与其调用的{{1 }}或pthread_cond_wait()。应当按照调度策略(如果适用)和好像每个线程都调用了pthread_cond_timedwait() 一样,将未阻塞的线程竞争互斥量。

pthread_mutex_lock()唤醒后获取互斥锁是精确的要求,就像线程已调用pthread_cond_[timed]wait()一样。

简而言之,任何线程都可以获取互斥锁。