Penjelasan wakeups palsu terdengar seperti bug yang tidak layak diperbaiki, benarkan?

30

Menurut artikel Wikipedia tentang Spurious Wakeups

+ msgstr "utas mungkin dibangunkan dari status menunggu meskipun tidak ada utas yang mengisyaratkan variabel kondisi".

Walaupun saya sudah tahu tentang 'fitur' ini, saya tidak pernah tahu apa yang sebenarnya menyebabkannya, pada artikel yang sama

"Wakeups palsu mungkin terdengar aneh, tetapi pada beberapa sistem multiprosesor, membuat wakeup kondisi sepenuhnya dapat diprediksi mungkin secara substansial memperlambat semua operasi variabel kondisi."

Kedengarannya seperti bug yang tidak layak diperbaiki, benarkan?

James
sumber
1
terkait: "Mengapa pthread_cond_wait memiliki wakeups palsu?", stackoverflow.com/questions/8594591/…
Florian Castellane

Jawaban:

39

TL; DR Asumsi ("kontrak") wakeups palsu adalah keputusan arsitektur yang masuk akal yang dibuat untuk memungkinkan implementasi thread sheduler yang realistis dan kuat.

"Pertimbangan kinerja" tidak relevan di sini, ini hanya kesalahpahaman yang meluas karena dinyatakan dalam referensi resmi yang diterbitkan. (referensi resmi mungkin memiliki kesalahan, Anda tahu - tanyakan saja kepada Galileo Galilei ) Artikel Wikipedia menyimpan referensi ke catatan yang Anda kutip hanya karena sangat cocok dengan pedoman formal mereka mengutip referensi yang diterbitkan.

Alasan yang jauh lebih menarik untuk memperkenalkan konsep bangun palsu disediakan dalam jawaban ini di SO yang didasarkan pada perincian tambahan yang disediakan dalam (versi yang lebih lama) dari artikel itu:

Artikel Wikipedia tentang wake up palsu memiliki berita gembira ini:

The pthread_cond_wait()fungsi dalam Linux diimplementasikan dengan menggunakan futexsystem call. Setiap panggilan sistem pemblokiran di Linux kembali dengan tiba-tiba EINTRketika proses menerima sinyal. ... pthread_cond_wait()tidak dapat memulai kembali menunggu karena mungkin akan melewatkan bangun yang nyata dalam waktu sedikit di luar futexsystem call ...

Bayangkan saja ... seperti kode apa pun, penjadwal thread mungkin mengalami pemadaman sementara karena sesuatu yang tidak normal terjadi pada perangkat keras / lunak yang mendasarinya. Tentu saja, kehati-hatian harus dilakukan agar hal ini terjadi sesering mungkin, tetapi karena tidak ada perangkat lunak yang kuat 100%, masuk akal untuk menganggap ini bisa terjadi dan berhati-hati pada pemulihan yang anggun jika jadwalnya mendeteksi hal ini (mis. dengan mengamati detak jantung yang hilang ).

Sekarang, bagaimana scheduler dapat pulih, dengan mempertimbangkan bahwa selama pemadaman itu bisa kehilangan beberapa sinyal yang dimaksudkan untuk memberi tahu utas menunggu? Jika scheduler tidak melakukan apa-apa, disebutkan thread "sial" hanya akan menggantung, menunggu selamanya - untuk menghindari ini, scheduler hanya akan mengirim sinyal ke semua utas menunggu.

Ini membuatnya perlu untuk membuat "kontrak" bahwa utas menunggu dapat diberitahukan tanpa alasan. Tepatnya, akan ada alasan - pemadaman penjadwal - tetapi karena utas dirancang (untuk alasan yang baik) untuk tidak mengetahui detail implementasi internal penjadwal, alasan ini kemungkinan lebih baik untuk ditampilkan sebagai "palsu".


Dari perspektif utas, ini agak menyerupai hukum Postel (alias prinsip ketahanan ),

menjadi konservatif dalam apa yang Anda lakukan, menjadi liberal dalam apa yang Anda terima dari orang lain

Asumsi wakeups palsu memaksa thread untuk menjadi konservatif dalam apa yang dilakukannya : menetapkan kondisi ketika memberi tahu thread lain, dan liberal dalam apa yang diterimanya : periksa kondisi setelah kembali dari menunggu dan ulangi tunggu jika belum ada.

agas
sumber
10
Ugh ... Hukum Postel ... alasan mengapa HTML dan segala macam teknologi web memiliki begitu banyak omong kosong yang dilemparkan ke dalamnya (misalnya, penerimaan HTML terhadap penandaan tag yang buruk). Selain itu, jawaban yang bagus.
Thomas Eding
3
Hukum Postel adalah mengapa banyak bug tidak diperhatikan selama bertahun-tahun karena hei, bahkan jika fungsi Anda mengembalikan output yang salah, aplikasi tersebut tampaknya masih berfungsi! Penemuan terbaik yang pernah ada.
Pacerier
2
@Pacerier: fungsi mengembalikan output yang salah tidak mengikuti hukum Postel (bagian konservatif).
YvesgereY
@Pacerier: OTOH, menuntut komponen lain agar ketat sehingga bug dapat ditangkap lebih awal adalah posisi yang menarik, berada di sisi prinsip 'Gagal Cepat' dan desain 'Berdasarkan Kontrak'.
YvesgereY
1

Itu tidak layak diperbaiki karena kode penelepon harus menggunakan perlakuan yang sama (memeriksa kondisi), untuk mengatasi kondisi balapan.

Satu pengobatan untuk dua masalah, yang saya simpulkan sebagai berikut:

Bangun palsu: utas menunggu dijadwalkan sebelum kondisinya ditetapkan.
Terpaksa tidur: utas menunggu dijadwalkan setelah kondisinya dipalsukan lagi.

Karena nanti mungkin terjadi, beberapa bahkan memperkenalkan kebangkitan palsu dalam kontrak:

  • untuk menegakkan praktik-praktik yang baik dengan mewajibkan loop predikat.
  • untuk memberikan kebebasan untuk implementasi penjadwal (termasuk opsi pemulihan darurat, seperti yang ditunjukkan oleh @gnat).

Referensi SO

YvesgereY
sumber
Saya ingin memberi ini +1, tetapi untuk gagasan bahwa seseorang secara sengaja memperkenalkan wakeups palsu untuk membuat penelepon menambahkan loop predikat untuk mengatasi tidur berlebihan yang dipaksakan. Saya menemukan itu tidak dapat dibayangkan.
ruakh
'Maksudnya adalah untuk memaksakan kode yang benar / kuat dengan memerlukan loop predikat.' Lihat tautan yang disediakan.
YvesgereY