ProgramlamaC++ çok iş parçacığı/servis geliştiricisi

C++'da çok iş parçacığıyla çalışırken hangi ayrıntılara dikkat edilmelidir? std::mutex, std::lock_guard, std::unique_lock arasındaki farkı açıklayın ve iş parçacıklarıyla güvenli bir çalışma örneği verin.

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap

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:

  • std::mutex — eşzamanlı erişim için temel kilitleme ilkesidir. Açık bir lock/unlock gerektirir.
  • std::lock_guard — mutex için RAII sarmalayıcıdır ve görünüm alanına giriş/çıkışta mutex'i otomatik olarak alır ve serbest bırakır.
  • std::unique_lock — daha evrensel bir RAII sarmalayıcıdır, manuel olarak kilitleme/serbest bırakma işlemlerine ve aynı zamanda mutex'in sahipliğini iş parçacıkları arasında taşımaya ve condition_variable kullanmaya olanak tanır.

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(); }

Sahte soru

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 }

Konunun inceliklerini bilmemekten kaynaklanan gerçek hata örnekleri


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ı.