2012-11-16 21 views
5

Tôi đã được nghiên cứu kỹ các câu trả lời chấp nhận vào SO câu dưới đây: C++0x has no semaphores? How to synchronize threads?Tại sao việc thực hiện điều kiện/mutex của semaphore yêu cầu một vòng lặp "while" trong hàm "wait()" của nó?

Trong việc thực hiện semaphore trong câu trả lời rằng, đây là việc thực hiện các wait() chức năng:

void wait() 
{ 
    boost::mutex::scoped_lock lock(mutex_); 
    while(!count_) 
     condition_.wait(lock); 
    --count_; 
} 

Tôi cố gắng để hiểu mục đích của điều kiện while(!count_).

Câu trả lời cho một câu hỏi SO (How does this implementation of semaphore work?) chỉ ra rằng khi notify_one() được gọi là trên biến điều kiện, đó có thể là HƠN MỘT chủ đề chờ đợi ngày mà biến điều kiện sẽ được đánh thức - vì thế nhu cầu sử dụng while vòng lặp. Tôi muốn xác nhận điều này - đó là câu trả lời đầy đủ và/hoặc chính xác hay có lý do khác tại sao vòng lặp while là cần thiết?

Nếu có nhiều hơn một luồng đánh thức, chuỗi nào sở hữu mutex? Càng suy nghĩ về nó, càng có nhiều bệnh được xác định là dường như có nhiều hơn một luồng có thể thức dậy do một cuộc gọi duy nhất đến notify_one(). Nó sẽ không thể cho BOTH chủ đề để xem giá trị count_ cao hơn 0, và tiến hành cả hai giảm count_, dẫn đến một giá trị count_ nhỏ hơn 0, và đánh bại mục đích (và chính xác) của semaphore?

Trả lời

3

Có thể có spurious wakeups hoặc notify_one có thể đánh thức nhiều hơn một chuỗi do chi tiết triển khai, như bạn đã đề cập.

Đánh thức nhiều luồng không có nghĩa là tất cả chúng có thể nhập phần được bảo vệ cùng một lúc, điều đó chỉ có nghĩa là khi ThreadA giải phóng khóa, ThreadB (đã được đánh thức cùng với ThreadA trong ví dụ trước) cũng được vào phần được bảo vệ. Bởi thời gian này ThreadA đã thực hiện công việc của mình, vì vậy ThreadB sẽ không thấy biến số count trong cùng trạng thái như ThreadA đã tìm thấy nó.

Các vấn đề liên quan