Nếu bạn không khóa mutex trong đường dẫn thay đổi điều kiện và tín hiệu, bạn có thể mất đánh thức. Hãy xem xét cặp quy trình này:
Quy trình A:
pthread_mutex_lock(&mutex);
while (condition == FALSE)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
Quy trình B (không chính xác):
condition = TRUE;
pthread_cond_signal(&cond);
Sau đó, hãy xem xét sự đan xen có thể có của các hướng dẫn này, condition
bắt đầu như FALSE
:
Process A Process B
pthread_mutex_lock(&mutex);
while (condition == FALSE)
condition = TRUE;
pthread_cond_signal(&cond);
pthread_cond_wait(&cond, &mutex);
Hiện condition
tại là TRUE
, nhưng Quy trình A bị kẹt khi chờ biến điều kiện - nó đã bỏ lỡ tín hiệu đánh thức. Nếu chúng tôi thay đổi Quy trình B để khóa mutex:
Quy trình B (đúng):
pthread_mutex_lock(&mutex);
condition = TRUE;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
... thì điều trên không thể xảy ra; thức dậy sẽ không bao giờ bị bỏ lỡ.
(Lưu ý rằng bạn thực sự có thể di chuyển pthread_cond_signal()
chính nó sau pthread_mutex_unlock()
, nhưng điều này có thể dẫn đến việc lập lịch các luồng kém tối ưu hơn và bạn nhất thiết phải khóa mutex đã có trong đường dẫn mã này do chính điều kiện thay đổi).
pthread_signal_cond()
có thể di chuyển sau khi mở khóa mutex, mặc dù có lẽ tốt hơn là không nên. Có lẽ đúng hơn khi nói rằng tại thời điểm bạn đang gọipthread_signal_cond()
, bạn sẽ cần phải khóa mutex để tự sửa đổi điều kiện.