Giải thích đánh thức giả có vẻ như là một lỗi không đáng để sửa, đúng không?


30

Theo bài viết trên Wikipedia về Sp Wake Wakeups

"một luồng có thể được đánh thức khỏi trạng thái chờ của nó mặc dù không có luồng nào báo hiệu biến điều kiện".

Mặc dù tôi đã biết về 'tính năng' này nhưng tôi chưa bao giờ biết điều gì thực sự gây ra cho đến khi, trong cùng một bài viết

"Đánh thức giả có vẻ lạ, nhưng trên một số hệ thống đa bộ xử lý, việc đánh thức điều kiện hoàn toàn có thể dự đoán được có thể làm chậm đáng kể tất cả các hoạt động biến điều kiện."

Nghe có vẻ như một lỗi không đáng để sửa, đúng không?


1
có liên quan: "Tại sao pthread_cond_wait có đánh thức giả?", stackoverflow.com/questions/8594591/
Florian Castellane

Câu trả lời:


39

TL; DR Giả định ("hợp đồng") của đánh thức giả là một quyết định kiến ​​trúc hợp lý được thực hiện để cho phép thực hiện mạnh mẽ thực tế của sheduler thread.

"Cân nhắc hiệu suất" không liên quan ở đây, đây chỉ là sự hiểu lầm đã trở nên phổ biến vì đã được nêu trong một tài liệu tham khảo có thẩm quyền được công bố. (tài liệu tham khảo có thẩm quyền có thể có sai sót, cậu biết đấy - chỉ cần hỏi Galileo Galilei ) bài viết trên Wikipedia giữ tham chiếu đến ghi chú mà bạn trích dẫn chỉ vì nó hoàn toàn phù hợp với chủ trương chính thức của họ về trích dẫn tài liệu tham khảo được công bố.

Lý do hấp dẫn hơn nhiều để giới thiệu khái niệm về đánh thức giả được cung cấp trong câu trả lời này tại SO dựa trên các chi tiết bổ sung được cung cấp trong một (phiên bản cũ hơn) của chính bài viết đó:

Bài viết trên Wikipedia về đánh thức giả có nội dung này:

Các pthread_cond_wait()chức năng trong Linux được thực hiện bằng cách sử dụng futexcuộc gọi hệ thống. Mỗi lệnh gọi hệ thống chặn trên Linux đột ngột trở lại EINTRkhi quá trình nhận được tín hiệu. ... pthread_cond_wait()không thể khởi động lại sự chờ đợi vì nó có thể bỏ lỡ một sự thức tỉnh thực sự trong thời gian ngắn bên ngoài futexcuộc gọi hệ thống ...

Chỉ cần nghĩ về nó ... giống như bất kỳ mã nào, bộ lập lịch luồng có thể bị mất điện tạm thời do có điều gì đó bất thường xảy ra trong phần cứng / phần mềm cơ bản. Tất nhiên, cần thận trọng để điều này xảy ra càng hiếm càng tốt, nhưng vì không có phần mềm mạnh mẽ nào 100% nên có lý khi cho rằng điều này có thể xảy ra và quan tâm đến sự phục hồi duyên dáng trong trường hợp nếu trình lập lịch phát hiện ra điều này (ví dụ bằng cách quan sát nhịp tim bị mất ).

Bây giờ, làm thế nào trình lập lịch biểu có thể phục hồi, có tính đến việc trong thời gian mất điện, nó có thể bỏ lỡ một số tín hiệu nhằm thông báo các chuỗi chờ? Nếu bộ lập lịch không làm gì, các chủ đề "không may mắn" được đề cập sẽ chỉ bị treo, chờ đợi mãi mãi - để tránh điều này, bộ lập lịch sẽ chỉ cần gửi tín hiệu đến tất cả các chủ đề đang chờ.

Điều này làm cho nó cần thiết để thiết lập một "hợp đồng" rằng chuỗi chờ có thể được thông báo mà không có lý do. Nói chính xác, sẽ có một lý do - tắt lịch trình - nhưng vì luồng được thiết kế (vì một lý do chính đáng) không để ý đến các chi tiết triển khai nội bộ của lịch trình, lý do này có thể tốt hơn để trình bày dưới dạng "giả".


Từ quan điểm chủ đề, điều này hơi giống với luật của Postel (còn gọi là nguyên tắc mạnh mẽ ),

Hãy thận trọng trong những gì bạn làm, hãy tự do trong những gì bạn chấp nhận từ người khác

Giả định về đánh thức giả buộc chủ đề phải thận trọng trong những gì nó làm : đặt điều kiện khi thông báo cho các luồng khác và tự do trong những gì nó chấp nhận : kiểm tra điều kiện khi có bất kỳ sự trở lại nào từ chờ đợi và lặp lại chờ đợi nếu chưa có.


10
Ugh ... Luật của Postel ... lý do tại sao HTML và tất cả các loại công nghệ web có quá nhiều thứ vớ vẩn (ví dụ: HTML chấp nhận lồng thẻ xấu). Điều đó sang một bên, câu trả lời tốt.
Thomas Eding

3
Luật của Postel là lý do tại sao nhiều lỗi không được phát hiện trong nhiều năm bởi vì, ngay cả khi chức năng của bạn trả lại đầu ra sai, ứng dụng dường như vẫn hoạt động! Phát minh tốt nhất bao giờ hết.
Pacerier

2
@Pacerier: chức năng trả về một đầu ra sai không tuân theo luật của Postel (phần bảo thủ).
YvesgereY

@Pacerier: OTOH, yêu cầu các thành phần khác phải nghiêm ngặt để các lỗi có thể bị phát hiện sớm hơn là một vị trí thú vị, sai lầm về nguyên tắc 'Fail Fast' và thiết kế 'Dựa trên hợp đồng'.
YvesgereY

1

Không đáng để sửa vì mã người gọi nên sử dụng cùng một cách xử lý (kiểm tra điều kiện) để xử lý tình trạng chủng tộc.

Một điều trị cho hai vấn đề, mà tôi tóm tắt bằng cách sau:

Đánh thức giả: luồng chờ được lên lịch trước khi điều kiện được thiết lập.
Buộc ngủ quên: chuỗi chờ được lên lịch sau khi điều kiện đã bị làm sai lệch một lần nữa.

Vì sau này có thể xảy ra, một số đã đi xa như giới thiệu đánh thức giả trong hợp đồng:

  • để thực thi các thực hành tốt bằng cách yêu cầu các vòng lặp vị ngữ.
  • để cung cấp một số quyền tự do cho việc thực hiện lập lịch trình (bao gồm tùy chọn khôi phục khẩn cấp, như được chỉ ra bởi @gnat).

Tài liệu tham khảo SO


Tôi muốn +1 điều này, nhưng với ý tưởng rằng ai đó cố tình đưa ra các đánh thức giả để khiến người gọi thêm các vòng lặp vị ngữ để giải quyết các giấc ngủ bị ép buộc. Tôi thấy rằng không thể tưởng tượng được.
ruakh

'Mục đích là buộc mã chính xác / mạnh mẽ bằng cách yêu cầu các vòng lặp vị ngữ.' Xem liên kết được cung cấp.
YvesgereY
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.