Hanya saja cara variabel kondisi diterapkan (atau awalnya).
Mutex digunakan untuk melindungi variabel kondisi itu sendiri . Itu sebabnya Anda membutuhkannya terkunci sebelum Anda menunggu.
Penantian akan "secara atomis" membuka mutex, memungkinkan orang lain mengakses variabel kondisi (untuk pensinyalan). Kemudian ketika variabel kondisi diisyaratkan atau disiarkan, satu atau lebih utas pada daftar tunggu akan dibangunkan dan mutex akan dikunci secara ajaib lagi untuk utas itu.
Anda biasanya melihat operasi berikut dengan variabel kondisi, menggambarkan cara kerjanya. Contoh berikut adalah utas pekerja yang diberikan pekerjaan melalui sinyal ke variabel kondisi.
thread:
initialise.
lock mutex.
while thread not told to stop working:
wait on condvar using mutex.
if work is available to be done:
do the work.
unlock mutex.
clean up.
exit thread.
Pekerjaan dilakukan dalam loop ini asalkan ada beberapa yang tersedia ketika menunggu kembali. Ketika utas telah ditandai untuk berhenti melakukan pekerjaan (biasanya oleh utas lain yang mengatur kondisi keluar kemudian menendang variabel kondisi untuk membangunkan utas ini), loop akan keluar, mutex akan terbuka dan utas ini akan keluar.
Kode di atas adalah model konsumen tunggal karena mutex tetap terkunci saat pekerjaan sedang dilakukan. Untuk variasi multi-konsumen, Anda dapat menggunakan, sebagai contoh :
thread:
initialise.
lock mutex.
while thread not told to stop working:
wait on condvar using mutex.
if work is available to be done:
copy work to thread local storage.
unlock mutex.
do the work.
lock mutex.
unlock mutex.
clean up.
exit thread.
yang memungkinkan konsumen lain untuk menerima pekerjaan saat ini sedang melakukan pekerjaan.
Variabel kondisi membebaskan Anda dari beban polling suatu kondisi alih-alih membiarkan utas lainnya memberi tahu Anda ketika sesuatu perlu terjadi. Utas lain dapat memberi tahu bahwa utas yang berfungsi tersedia sebagai berikut:
lock mutex.
flag work as available.
signal condition variable.
unlock mutex.
Sebagian besar dari apa yang sering keliru disebut wake ups palsu umumnya selalu karena banyak utas telah ditandai dalam pthread_cond_wait
panggilan mereka (siaran), seseorang akan kembali dengan mutex, melakukan pekerjaan, kemudian menunggu kembali.
Kemudian utas sinyal kedua bisa muncul ketika tidak ada pekerjaan yang harus dilakukan. Jadi Anda harus memiliki variabel tambahan yang menunjukkan bahwa pekerjaan harus dilakukan (ini secara inheren dilindungi mutex dengan pasangan condvar / mutex di sini - utas lain yang diperlukan untuk mengunci mutex sebelum mengubahnya namun).
Ini adalah teknis mungkin untuk thread untuk kembali dari kondisi menunggu tanpa ditendang oleh proses lain (ini adalah wakeup palsu asli) tetapi, dalam semua bertahun-tahun saya bekerja di pthreads, baik dalam pengembangan / jasa dari kode dan sebagai pengguna dari mereka, saya tidak pernah sekalipun menerima salah satu dari ini. Mungkin itu hanya karena HP memiliki implementasi yang layak :-)
Dalam kasus apa pun, kode yang sama yang menangani kasus yang salah juga menangani bangun palsu asli juga karena bendera yang tersedia untuk pekerjaan tidak akan ditetapkan untuk mereka.