为什么在调用`pthread_cond_signal`前调用`pthread_mutex_unlock`?
问题描述:
从多处理器编程的艺术,为什么在调用`pthread_cond_signal`前调用`pthread_mutex_unlock`?
1 #include <pthread.h>
2 #define QSIZE 16
3 typedef struct {
4 int buf[QSIZE];
5 long head, tail;
6 pthread_mutex_t *mutex;
7 pthread_cond_t *notFull, *notEmpty;
8 } queue;
9 void queue_enq(queue* q, int item) {
10 // lock object
11 pthread_mutex_lock (q->mutex);
12 // wait while full
13 while (q->tail - q->head == QSIZE) {
14 pthread_cond_wait (q->notFull, q->mutex);
15 }
16 q->buf[q->tail % QSIZE] = item;
17 q->tail++;
18 // release lock
19 pthread_mutex_unlock (q->mutex);
20 // inform waiting dequeuers
21 pthread_cond_signal (q->notEmpty);
22 }
和高级编程在Unix环境
void
enqueue_msg(struct msg *mp)
{
pthread_mutex_lock(&qlock);
mp->m_next = workq;
workq = mp;
pthread_mutex_unlock(&qlock);
pthread_cond_signal(&qready);
}
为什么pthread_mutex_unlock
调用pthread_cond_signal
之前叫什么名字?
In Java, unlocking is called after calling signal. 那么,为什么不同?
谢谢。
答
如果pthread_cond_signal
将被称为被解锁的互斥体之前,你介绍的可能性,即一个服务员(一个在第一个例子“dequeuer”)会立即清醒和尝试互斥之前锁定互斥被解锁信号线程。因为你知道出列者需要做的第一件事是锁定互斥锁,所以你几乎鼓励了线程争用以及由此产生的(不必要的)上下文切换。
在信令之前解锁互斥消除了争用的来源。
我认为这是错误的。看看https://*.com/questions/4544234/calling-pthread-cond-signal-without-locking-mutex –
@JerryJeremiah谢谢。在APUE中,有一个例子在发送信号之前也释放锁定。查看我的更新。 – Ben