Wenn Sie den Mutex nicht im Codepfad sperren, der den Zustand und die Signale ändert, können Sie das Aufwecken verlieren. Betrachten Sie dieses Prozesspaar:
Prozess A:
pthread_mutex_lock(&mutex);
while (condition == FALSE)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
Prozess B (falsch):
condition = TRUE;
pthread_cond_signal(&cond);
Betrachten Sie dann diese mögliche Verschachtelung von Anweisungen, wobei condition
Folgendes beginnt FALSE
:
Process A Process B
pthread_mutex_lock(&mutex);
while (condition == FALSE)
condition = TRUE;
pthread_cond_signal(&cond);
pthread_cond_wait(&cond, &mutex);
Das condition
ist jetzt TRUE
, aber Prozess A wartet nicht mehr auf die Bedingungsvariable - er hat das Wecksignal verpasst. Wenn wir Prozess B ändern, um den Mutex zu sperren:
Prozess B (richtig):
pthread_mutex_lock(&mutex);
condition = TRUE;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
... dann kann das oben genannte nicht auftreten; Das Aufwachen wird nie fehlen.
(Beachten Sie, dass Sie können tatsächlich die bewegen pthread_cond_signal()
sich nach dem pthread_mutex_unlock()
, aber in weniger optimalen Planung von Threads zur Folge haben kann, und Sie haben notwendigerweise den Mutex gesperrt bereits in diesem Codepfad aufgrund Änderung der Bedingung selbst).
pthread_signal_cond()
kann der nach dem Mutex-Unlock verschoben werden, obwohl es wahrscheinlich besser ist, dies nicht zu tun . Es ist vielleicht richtiger zu sagen, dass Sie an dem Punkt, an dem Sie anrufenpthread_signal_cond()
, den Mutex bereits gesperrt haben müssen, um die Bedingung selbst zu ändern.