Pertanyaan Apakah saya perlu mutex untuk membaca?


Saya memiliki kelas yang memiliki keadaan (enum sederhana) dan yang diakses dari dua utas. Untuk mengubah keadaan saya menggunakan mutex (boost :: mutex). Apakah aman untuk memeriksa keadaan (misalnya membandingkan state_ == ESTABLISHED) atau apakah saya harus menggunakan mutex dalam kasus ini juga? Dengan kata lain, apakah saya perlu mutex ketika saya hanya ingin membaca variabel yang dapat ditulis bersamaan oleh thread lain?


32
2017-10-06 12:05


asal


Jawaban:


Tergantung.

Bahasa C ++ tidak mengatakan apa-apa tentang benang atau atomicity.

Tetapi pada paling CPU modern, membaca bilangan bulat adalah operasi atom, yang berarti Anda akan selalu membaca nilai yang konsisten, bahkan tanpa mutex.

Namun, tanpa mutex, atau beberapa bentuk sinkronisasi lainnya, compiler dan CPU bebas untuk menyusun ulang pembacaan dan penulisan, jadi apa pun yang lebih kompleks, apa pun yang melibatkan mengakses beberapa variabel, masih tidak aman dalam kasus umum.

Dengan asumsi utas penulis memperbarui beberapa data, dan kemudian menetapkan tanda bilangan bulat untuk menginformasikan utas lainnya bahwa data tersedia, ini bisa diatur ulang sehingga bendera disetel sebelum memperbarui data. Kecuali Anda menggunakan mutex atau bentuk lain dari penghalang ingatan.

Jadi jika Anda menginginkan perilaku yang benar, Anda tidak memerlukan mutex seperti itu, dan tidak masalah jika thread lain menulis ke variabel saat Anda membacanya. Ini akan menjadi atom kecuali Anda sedang bekerja pada CPU yang sangat tidak biasa. Tapi kamu melakukan memerlukan penghalang memori untuk mencegah pengurutan ulang di compiler atau CPU.


13
2017-10-13 14:37



Anda memiliki dua utas, mereka bertukar informasi, ya Anda memerlukan mutex dan Anda mungkin juga perlu menunggu bersyarat.

Dalam contoh Anda (bandingkan state_ == ESTABLISHED) menunjukkan bahwa thread # 2 sedang menunggu utas # 1 untuk memulai koneksi / status. Tanpa mutex atau conditional / events, thread # 2 harus melakukan polling terhadap status secara terus menerus.

Benang digunakan untuk meningkatkan kinerja (atau meningkatkan daya tanggap), polling biasanya menghasilkan kinerja yang menurun, baik dengan mengkonsumsi banyak CPU atau dengan memperkenalkan latensi karena interval jajak pendapat.


9
2017-10-06 12:22



Iya nih. Jika thread a membaca variabel ketika thread b menulis untuk itu, Anda dapat membaca nilai yang tidak terdefinisi. Operasi baca dan tulis tidak bersifat atom, terutama pada sistem multi-prosesor.


3
2017-10-06 12:10



Secara umum Anda tidak, jika variabel Anda dideklarasikan dengan "volatile". Dan HANYA jika itu adalah variabel tunggal - jika tidak Anda harus benar-benar hati-hati tentang kemungkinan balapan.


0
2017-10-06 12:11



Akses ke enum (baca atau tulis) harus dijaga.

Hal lain: Jika thread contention kurang dan thread milik proses yang sama maka bagian Kritis akan lebih baik daripada mutex.


0
2017-10-06 12:13



sebenarnya, tidak ada alasan untuk mengunci akses ke objek untuk membaca. Anda hanya ingin menguncinya saat menulis untuk itu. ini persis seperti apa kunci penulis-pembaca. itu tidak mengunci objek selama tidak ada operasi tulis. itu meningkatkan kinerja dan mencegah kebuntuan. lihat tautan berikut untuk penjelasan lebih terperinci:

wikipedia codeproject


0
2017-10-13 14:15