问题
From The Art of Multiprocessor Programming,
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 }
and from Advanced Programming in Unix Environment
void
enqueue_msg(struct msg *mp)
{
pthread_mutex_lock(&qlock);
mp->m_next = workq;
workq = mp;
pthread_mutex_unlock(&qlock);
pthread_cond_signal(&qready);
}
Why is pthread_mutex_unlock
called before calling pthread_cond_signal
?
In Java, unlocking is called after calling signal. So why is the difference?
Thanks.
回答1:
If pthread_cond_signal
were to be called before the mutex was unlocked, you introduce the possibility that a waiter (a 'dequeuer' in the first example) will immediately awake and attempt to lock the mutex before the mutex is unlocked by the signaling thread. Because you know the first thing the dequeuer is going to need to do is lock the mutex, you're almost encouraging thread contention and the resultant (unnecessary) context switching.
Unlocking the mutex before signaling eliminates this source of contention.
来源:https://stackoverflow.com/questions/46762527/why-is-pthread-mutex-unlock-called-before-calling-pthread-cond-signal