Multithreading | std::mutex - 1

Mutex (mutual exclusion)  işletim sistemlerinde olan bir senkronizasyon nesnesidir. Bir mutex'e ayni anda sadece bir thread sahip olabilmektedir. Multithreading sistemlerde deadlock 'lari ve race condition 'ları  engellemek icin kullanilan bir senkronizasyon nesnesidir.
Mutex bir thread tarafından ele alınır ve mutex’in sahipliğini alan thread'ten başka bir thread bu mutex’i ele almaya çalışınca bloke olur. Mutex’in sahibi olan thread mutex nesnesini bırakana kadar diğer thread bekleme moduna geçer. 


Yukarıdaki örneğe bakılırsa 10 tane thread 'lik havuz oluşturulmuş ve daha sonra join edilmiştir. Fakat std::vector veri yapısı burada thread'ler arasında senkronizasyon amaçlı olarak korunmadığı için aşağıda görülebileceği üzere program hatayla sonlanmıştır. 


Thread'ler eğer bir veri yapısını ortak olarak kullanmaları gerekiyorsa senkronizasyon nesnelerinden faydalanmak gerekmektedir. Bundan sonra yazının sonuna kadar senkronizasyon nesnesi olarak mutex 'leri kullanacağız.


Yukarıdaki örnekte mutex 'in içsel fonksiyonu olan lock() ile thread mutex nesnesini kilitler veya başka bir thread tarafından kilitlenmiş ise istek gönderen thread beklemeye alınır.


Yukarıdaki örnek çalıştırıldığında görebileceğiniz üzere program hatasız çalışıyor ve her thread istenen ekleme işlemini gerçekleştirdiği görülebilir. Ama thread önceliği gibi bir kısıtlama olmadığı için aynı program tekrar çalıştırıldığında ekleme sıralamasının farklı olduğu görülebilmektedir.


Yukarıdaki örnekte ise mutex nesnesinin lock/unlock işlemleri std::lock_guard ile sağlanmıştır. Bu sayede mutex'in unlock mekanizmasını unutmak diye bir hatanında önüne geçilmiş olmaktadır.


Yukarıdaki örnekte ise mutex nesnesinin lock/unlock işlemleri std::unique_lock ile gerçeklenmiştir. std::unique_lock sınıfının constructor'ının ikinci parametresine std::defer_lock parametresi geçilerek construction aşamasında mutex'in lock işleminin yapılmamasını sağlayabiliriz. Daha sonra bu işlemi unique_lock sınıfının lock() ve unlock() fonksiyonlarıyla yapabiliriz. Bu noktada eğer unlock işlemini unutursak std::unique_lock sınıfının destructor'ı bizim yerimize yapacaktır.