Modern C++'da (C++11'den itibaren) çok iş parçacığıyla çalışmak için zengin bir araç seti bulunmaktadır: std::thread, mutex'ler ve kaynaklara erişimi yönetmek için çeşitli sarmalayıcı nesneler. İş parçacıkları arasındaki güvenli etkileşim, aşağıdaki bileşenlerin anlaşılmasını gerektirir:
Yarışmaların önüne geçmek için her zaman mümkünse RAII sarmalayıcılarını kullanın. Aynı mutex'i yeniden almak, bir deadlock'a yol açar (bu, rekürsif bir mutex değilse).
Doğru çalışma örneği:
#include <iostream> #include <mutex> #include <thread> std::mutex mtx; void printThreadSafe(int id) { std::lock_guard<std::mutex> lock(mtx); std::cout << "İş parçacığı " << id << std::endl; } int main() { std::thread t1(printThreadSafe, 1); std::thread t2(printThreadSafe, 2); t1.join(); t2.join(); }
std::lock_guardstd::mutex kullanarak condition_variable ile koşullu senkronizasyon uygulamak mümkün mü?
Cevap: Hayır! std::condition_variable ile çalışmak için mutlaka std::unique_lockstd::mutex gereklidir, çünkü lock_guard, bekleme sırasında gerekli olan kilitleme kontrol yöntemlerini (örneğin, geçici olarak serbest bırakma — unlock — ve sonra tekrar alma) sağlamaz.
Örnek:
std::mutex mtx; std::condition_variable cv; bool ready = false; void waitForEvent() { std::unique_lock<std::mutex> lock(mtx); cv.wait(lock, []{return ready;}); // Devam eden işleme }
Hikaye
Projede mtx.lock()/mtx.unlock() ile manuel çalışma kullanılıyordu. Lock/unlock arasında bir istisna fırlatıldığında mutex kilitli kalıyordu — birçok iş parçacığı "askıda" kalıyordu. RAII'ye (
std::lock_guard) geçildiğinde problem ortadan kalktı.
Hikaye
std::condition_variable ile bildirim yaparken std::unique_lock yerine std::lock_guard kullandık. Sonuç olarak, program yeni derleyicilerde derlenmedi ve eski derleyicide ise tutarsız API nedeniyle runtime assert meydana geldi.
Hikaye
Kodu std::lock_guard için unlock() çağrısı ile mutex'e "manuel" erişim kontrolü sağlanmaya çalışılıyordu. Bu, farklı derleyicilerde belirsiz davranışa, bazen uygulamanın çökmesine neden oldu. lock_guard'ın manuel serbest bırakma desteği olmadığı anlaşıldı, unique_lock'a geçiş yapıldı.