2015-09-10 15 views
5

Tôi đã thử nghiệm kịch bản này trong một số môi trường, và tôi đã nhận dòng chảy sau:Có thể một pthread_cond_wait() tiêu thụ nhiều pthread_cond_signal()?

expected

Tuy nhiên, từ các trang người đàn ông (http://linux.die.net/man/3/pthread_cond_wait) hoặc (http://linux.die.net/man/3/pthread_cond_signal), tôi không thể tìm thấy bất kỳ sự đảm bảo rằng sau kịch bản không thể xảy ra:

scenario

nào là 2 bài làm một tín hiệu thể chạy trước bất kỳ chờ đợi chủ đề có cơ hội để chạy. (Lịch khả năng)

[Bây giờ, tôi biết rằng nếu điều này được thực hiện với Cột, kịch bản thứ hai sẽ không bao giờ xảy ra ... Tuy nhiên trong trường hợp của tôi, tôi thực sự cần phải làm điều này với cond-vars!]

Trong trường hợp của tôi, mỗi bài viết gia tăng vị từ, vì vậy khi chờ đợi Thread2 đánh thức nó sẽ kiểm tra vị từ (mà trong trường hợp này được tăng lên 2), làm cho thread không ngủ nữa và nó sẽ giảm vị từ 1 (ý nghĩa một bài đăng đã được tiêu thụ). Nếu kịch bản này có thể xảy ra, nó có nghĩa là "Thread1" có thể không thức dậy cho đến khi một bài viết tiếp theo xảy ra, mặc dù biến vị ngữ được tăng gấp đôi (bài) và chỉ giảm một lần (Thread2 chờ). Thậm chí tệ hơn, lần chờ thứ ba có thể không bao giờ chặn vì nó sẽ tiêu thụ số liệu vị ngữ đang chờ xử lý trước đó.

Tôi chưa thể kích hoạt vấn đề này, nhưng có ai biết nếu đây là một tình huống có thể xảy ra không?


LƯU Ý để vượt qua khả năng này, tôi đã thay thế pthread_cond_signal() bởi pthread_cond_broadcast() vì vậy cả hai Thread1Thread2 được đảm bảo để thức dậy và tiêu thụ gia số 2. Tuy nhiên, giải pháp này giảm một chút (có thể thậm chí không đáng kể) hiệu suất, và tôi đặt cược nó không phải là rõ ràng cho bất cứ ai nhìn vào lý do tại sao chúng tôi đang sử dụng chương trình phát sóng ở đây.

Trả lời

7

Không, không thể pthread_cond_wait() tiêu thụ hai tín hiệu.

pthread_cond_signal() được đảm bảo để đánh thức ít nhất một chuỗi hiện đang chờ trên biến điều kiện. Khi chuỗi đã được báo hiệu, nó không còn chờ biến điều kiện nữa (mặc dù nó có thể vẫn đang chờ trên mutex được liên kết), do đó, pthread_cond_signal() tiếp theo phải đánh thức một chuỗi chờ khác nhau (nếu có).

(Trong biểu đồ thứ hai của bạn, tín hiệu thứ hai phải nhắm mục tiêu một chủ đề khác không phải là Thread2, vì Thread2 không còn chờ trên biến điều kiện tại điểm đó nữa).

Các từ ngữ chính xác trong POSIX spec for pthread_cond_signal là:

Chức năng pthread_cond_signal() phải bỏ chặn ít nhất một trong những đề đã bị khóa với điều kiện biến cond quy định (nếu có đề bị chặn trên cond).

+0

Cảm ơn câu trả lời. Tôi đã giả định rằng một sợi đã bị chặn cho đến thời điểm thực hiện (thời điểm mà nó cố gắng để có được mutex). Vì vậy, có một cơ chế trên hệ điều hành để "tag" các chủ đề? (nghĩa là mỗi pthread_cond_signal() sẽ "bỏ gắn" một luồng khác nhau?) – Pacheco

+1

@Pacheco: Nó phụ thuộc vào hệ điều hành được thực hiện như thế nào, nhưng nói chung các quá trình bị chặn trên biến điều kiện sẽ nằm trong hàng đợi chờ và báo hiệu biến điều kiện nguyên tử di chuyển một quá trình ra khỏi hàng đợi đó. – caf

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