Saya memiliki aplikasi multithread yang harus sering membaca beberapa data, dan terkadang data tersebut diperbarui. Saat ini mutex menjaga akses ke data itu tetap aman, tetapi itu mahal karena saya ingin beberapa utas dapat membaca secara bersamaan, dan hanya menguncinya ketika pembaruan diperlukan (utas pembaruan dapat menunggu utas lain selesai) .
Saya pikir inilah yang boost::shared_mutex
seharusnya dilakukan, tetapi saya tidak jelas tentang cara menggunakannya, dan belum menemukan contoh yang jelas.
Adakah yang punya contoh sederhana yang bisa saya gunakan untuk memulai?
c++
multithreading
boost
mutex
boost-thread
kevin42
sumber
sumber
Jawaban:
Sepertinya Anda akan melakukan sesuatu seperti ini:
sumber
1800 INFORMASI kurang lebih benar, tetapi ada beberapa masalah yang ingin saya perbaiki.
Juga Perhatikan, tidak seperti shared_lock, hanya satu utas yang dapat memperoleh upgrade_lock pada satu waktu, bahkan ketika itu tidak ditingkatkan (yang menurut saya canggung ketika saya menemukannya). Jadi, jika semua pembaca Anda adalah penulis bersyarat, Anda perlu mencari solusi lain.
sumber
boost::unique_lock< boost::shared_mutex > lock(lock);
membacaboost::unique_lock< boost::shared_mutex > lock(
_access);
?Sejak C ++ 17 (VS2015) Anda dapat menggunakan standar untuk kunci baca-tulis:
Untuk versi yang lebih lama, Anda dapat menggunakan boost dengan sintaks yang sama:
sumber
typedef boost::unique_lock< Lock > WriteLock; typedef boost::shared_lock< Lock > ReadLock;
.Hanya untuk menambahkan beberapa info empiris, saya telah menyelidiki seluruh masalah kunci yang dapat diupgrade, dan Contoh untuk meningkatkan shared_mutex (banyak baca / satu tulisan)? adalah jawaban yang bagus menambahkan info penting bahwa hanya satu utas yang dapat memiliki upgrade_lock meskipun tidak ditingkatkan, itu penting karena itu berarti Anda tidak dapat meningkatkan dari kunci bersama menjadi kunci unik tanpa melepaskan kunci bersama terlebih dahulu. (Ini telah dibahas di tempat lain tetapi utas yang paling menarik ada di sini http://thread.gmane.org/gmane.comp.lib.boost.devel/214394 )
Namun saya menemukan perbedaan penting (tidak berdokumen) antara utas menunggu peningkatan ke kunci (yaitu perlu menunggu semua pembaca untuk melepaskan kunci bersama) dan kunci penulis menunggu hal yang sama (yaitu unique_lock).
Utas yang menunggu unique_lock di shared_mutex memblokir pembaca baru yang masuk, mereka harus menunggu permintaan penulis. Hal ini memastikan pembaca tidak membuat penulis kelaparan (namun saya yakin penulis dapat membuat pembaca kelaparan).
Utas yang menunggu upgradeable_lock untuk meningkatkan memungkinkan utas lain mendapatkan kunci bersama, jadi utas ini bisa kelaparan jika pembaca sangat sering.
Ini adalah masalah penting untuk dipertimbangkan, dan mungkin harus didokumentasikan.
sumber
Terekhov algorithm
memastikan1.
, penulis tidak bisa membuat pembacanya kelaparan. Lihat ini . Tapi2.
memang benar. Upgrade_lock tidak menjamin keadilan. Lihat ini .Gunakan semaphore dengan hitungan yang sama dengan jumlah pembaca. Biarkan setiap pembaca mengambil satu hitungan semafor untuk membaca, dengan cara itu mereka semua dapat membaca pada waktu yang sama. Kemudian biarkan penulis mengambil SEMUA hitungan semaphore sebelum menulis. Hal ini menyebabkan penulis menunggu semua pembacaan selesai dan kemudian memblokir pembacaan saat menulis.
sumber
Tanggapan yang luar biasa oleh Jim Morris, saya menemukan ini dan butuh beberapa saat untuk memikirkannya. Berikut adalah beberapa kode sederhana yang menunjukkan bahwa setelah mengirimkan "request" untuk unique_lock boost (versi 1.54) memblokir semua permintaan shared_lock. Ini sangat menarik karena menurut saya memilih antara unique_lock dan upgradeable_lock memungkinkan jika kita ingin menulis prioritas atau tanpa prioritas.
Juga (1) dalam posting Jim Morris tampaknya bertentangan dengan ini: Boost shared_lock. Baca lebih disukai?
sumber