0

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.

  • I think it is wrong. Have a look at https://stackoverflow.com/questions/4544234/calling-pthread-cond-signal-without-locking-mutex – Jerry Jeremiah Oct 16 '17 at 03:34
  • @JerryJeremiah Thanks. In APUE, there is an example which also release lock before signaling. See my update. –  Oct 16 '17 at 03:43

1 Answers1

2

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.

Myk Willis
  • 12,306
  • 4
  • 45
  • 62
  • Thanks. Why is the order reversed in Java? –  Oct 16 '17 at 12:24
  • @Ben The order is not "reversed" in java. You, the programmer, decides which order you want to call these in, in both Java or pthreads. The safe thing is to signal the condition when the mutex is held, if you want to call it without the mutex held, you need to perform thorough analyzis of your code to either avoid missing signals on the condition, or write your logic so it does not matter if condition signals are missed. – nos Oct 16 '17 at 13:11
  • @nos: thanks. In the examples for pthread here, is there some guarantee to avoid missing signals on the condition? Note that both the examples in pthread and in Java are from the same book: The Art of Multiprocessor Programming. –  Oct 16 '17 at 17:09