2017-10-16 9 views
0

なぜ `pthread_mutex_unlock`が` pthread_cond_signal`を呼び出す前に呼び出されていますか?マルチプログラミングの技術から

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_unlockpthread_cond_signalを呼び出す前に呼ばれているのですか?

In Java, unlocking is called after calling signal. なぜ違いはありますか?

ありがとうございました。

+0

私は間違っていると思います。 https://stackoverflow.com/questions/4544234/calling-pthread-cond-signal-without-locking-mutex –

+0

@JerryJeremiahありがとうございます。 APUEには、シグナリングの前にロックを解除する例もあります。私の更新を参照してください。 – Ben

答えて

1

pthread_cond_signalはmutexがアンロックされた前に呼び出されるとしたら、あなたはmutexがでロックが解除される前に、ウェイター(最初の例では「デキュー」)はすぐに目を覚ましやミューテックスをロックしようとしている可能性を紹介シグナルスレッド。デキュー者が最初に行う必要があることは、mutexをロックすることであることを知っているので、スレッドの競合とその結果の(不要な)コンテキスト切り替えを奨励しています。

シグナリングの前にmutexをロック解除すると、この競合の原因がなくなります。

+0

ありがとうございます。 Javaで注文が逆転したのはなぜですか? – Ben

+0

@Ben注文はJavaでは「逆転」していません。プログラマは、Javaまたはpthreadの両方でこれらを呼び出す順序を決定します。安全なことは、ミューテックスが保持されている状態を通知することです。ミューテックスが保持されていない状態で呼び出す場合は、コードの完全な解析を実行して、状態信号が欠落しているかどうかは関係ありません。 – nos

+0

@nos:ありがとう。ここでのpthreadの例では、状態の信号が欠落しないようにするための保証はありますか? pthreadとJavaの両方の例は、同じ本の「マルチプロセッサプログラミングの技術」のものです。 – Ben

関連する問題