std::lock_guard
- C++ kursu
- İleri seviye
- Ders 21/83
- 5 dk
std::lock_guard ile RAII kilit öğrenirsin.
std::lock_guard
std::lock_guard, mutex için RAII sarmalayıcıdır. Kurucuda lock çağırır, yıkıcıda unlock çağırır. Kapsamdan çıkınca (scope ends) otomatik olarak kilit açılır. Sözdizimi: std::lock_guard<std::mutex> lk(m);.
Bu, lock ve unlock yazmayı unutmayı engeller. Özellikle istisna (exception) fırlatıldığında kilit yine de açılır; çünkü yıkıcı her durumda çalışır. lock_guard yalnızca kurucu ve yıkıcıya sahiptir; taşıma veya kopyalama desteklenmez. Sade ve güvenli kritik bölüm yönetimi için idealdir.
İstisna güvenliği
lock_guard'ın asıl gücü, istisna fırlatıldığında bile kilidi açmasıdır. m.lock(); kullansaydık ve sonrasında throw çalışsaydı, unlock çağrılmazdı; kilit sonsuza dek kalırdı. lock_guard bu sorunu ortadan kaldırır.
Bu, RAII (Resource Acquisition Is Initialization) ilkesinin tipik bir örneğidir. Kaynak (kilit) nesnenin ömriyle bağlanır; nesne yok olduğunda kaynak otomatik bırakılır. Modern C++'ta std::unique_ptr, std::fstream ve std::lock_guard bu ilkeyle çalışır.
Uygulama lock_guard ile counter
Global int counter = 0; ve std::mutex m; tanımla. void add_once() yaz; gövdede std::lock_guard<std::mutex> lk(m); counter++; olsun. main içinde iki iş parçacığı başlat, ikisini de join ile bekle, sonra std::cout << counter; yaz.
Başlangıç kodu
#include <iostream>
#include <thread>
#include <mutex>
int counter = 0;
std::mutex m;
// add_once fonksiyonunu yaz
int main() {
// İki iş parçacığı başlat, bekle, yazdır
return 0;
}Örnek çözüm
#include <iostream>
#include <thread>
#include <mutex>
int counter = 0;
std::mutex m;
void add_once() {
std::lock_guard<std::mutex> lk(m);
counter++;
}
int main() {
std::thread t1(add_once);
std::thread t2(add_once);
t1.join();
t2.join();
std::cout << counter;
return 0;
}Beklenen çıktı
2
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 lock_guard kilidi ne zaman açar?
- Kapsamdan çıkınca Doğru cevap
- Program sonunda
- Açıkça unlock çağrılınca
- İş parçacığı uyuyunca
Açıklama: lock_guard, yıkıcısıyla kapsam sonunda kilidi açar.
2 İfadeyi rolüne eşle
| Kavram | Anlamı |
|---|---|
std::lock_guard<std::mutex> lk(m) |
RAII sarmalayıcı |
lk kurucu |
lock çağırır |
lk yıkıcı |
unlock çağırır |
{ ... } |
Kapsam sonu |
3 lock_guard satırını tamamla
void add_once() {
std::____<std::mutex> lk(m);
counter++;
}
void add_once() {
std::lock_guard<std::mutex> lk(m);
counter++;
}
Açıklama: std::lock_guard<std::mutex> lk(m); RAII ile kilit alır.