Java 为什么在调用“pthread\u cond\u signal”之前调用了“pthread\u mutex\u unlock”?

Java 为什么在调用“pthread\u cond\u signal”之前调用了“pthread\u mutex\u unlock”?,java,concurrency,synchronization,pthreads,monitor,Java,Concurrency,Synchronization,Pthreads,Monitor,从多处理器编程的艺术来看 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

从多处理器编程的艺术来看

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 }
为什么调用
pthread\u mutex\u unlock\code>之前调用了
pthread\u cond\u signal

那么为什么会有区别呢


谢谢。

如果在解锁互斥锁之前调用了
pthread\u cond\u signal
,则会引入一种可能性,即服务员(第一个示例中的“出列者”)会立即醒来,并尝试在通过信令线程解锁互斥锁之前锁定互斥锁。因为您知道出列器需要做的第一件事是锁定互斥锁,所以您几乎鼓励线程争用和由此产生的(不必要的)上下文切换


在发信号之前解锁互斥锁可以消除这种争用源。

我认为这是错误的。看看@JerryJeremiah谢谢。在APUE中,有一个示例也在发信号之前释放锁。请看我的更新。谢谢。为什么Java中的顺序是颠倒的?@Ben Java中的顺序不是“颠倒的”。程序员可以决定在Java或pthread中调用它们的顺序。安全的做法是在保持互斥时发出条件信号,如果您想在不保持互斥的情况下调用它,您需要对代码进行彻底的分析,以避免条件信号丢失,或者编写逻辑,这样条件信号丢失就无关紧要了。@nos:谢谢。在这里的pthread示例中,是否有一些保证可以避免在该条件下丢失信号?请注意,pthread和Java中的示例都来自同一本书:《多处理器编程的艺术》。
void
enqueue_msg(struct msg *mp)
{

    pthread_mutex_lock(&qlock);
    mp->m_next = workq;
    workq = mp;
    pthread_mutex_unlock(&qlock);
    pthread_cond_signal(&qready);

}