2013-03-02 9 views
36

Zamierzam użyć boost::mutex z boost/thread/mutex.hpp. Istnieje kilka sposobów, aby zablokować/odblokować mutex: z scoped_lock, unique_lock, lock_guard, funkcje składowe mutex za ::lock() i ::unlock() i funkcji nie będących członkami lock() i unlock().doładowanie scoped_lock kontra zwykły zamek/odblokowanie

Zauważyłem, że boost::scoped_mutex jest jednym z najpopularniejszych sposobów używania mutex. Dlaczego jest to lepsze niż funkcje składowe ::lock() i ::unlock()?

Szczególnie, dlaczego należy używać

{ 
    boost::scoped_lock lock(mutex) 
    // ... 
    // read/output sharing memory. 
    // ... 
} 

zamiast

mutex.lock() 
// ... 
// read/output sharing memory. 
// ... 
mutex.unlock() 

jest scoped_lock lepiej tylko dlatego, że jakiś styl kodowania punktu widzenia lub nie jest ::lock()/::unlock() „gwint wystarczająco bezpieczny”?

Odpowiedz

62

Dlaczego preferowane są funkcje członkowskie :: lock() i :: unlock()?

Z tego samego powodu, dlaczego RAII idiom stał się popularny w ogóle (to tylko jeden z jej licznych przypadkach): ponieważ możesz być pewien, że don”pozostawić obecny zakres bez odblokowywania mutex.

Zauważ, że nie jest to tylko około zapominając zadzwonić unlock(): wyjątek może wystąpić podczas Twojego mutex jest zablokowany i nie może zostać osiągnięty wezwanie do unlock(), nawet jeśli nie mają żadnego return oświadczenie między swoje zadzwoń pod numer lock() i zadzwoń pod numer unlock().

m.lock() // m is a mutex 
// ... 
foo(); // If this throws, your mutex won't get unlocked 
// ... 
m.unlock() 

W takim przypadku destruktor Twojego scoped_lock straży zostanie wywołany podczas zwijania stosu, upewniając się, że związane muteksu zawsze zostanie zwolniony.

{ 
    boost::scoped_lock lock(m); // m is a mutex 
    // ... 
    foo(); // If this throws, your RAII wrapper will unlock the mutex 
    // ... 
} 

Ponadto w wielu sytuacjach to poprawi czytelność kodzie jest, że nie będzie trzeba dodać wywołanie unlock() przed każdym return oświadczeniu.

+0

dziękuję za jasne wyjaśnienie. – Max

+0

@Max: Cieszę się, że pomogło –

2

można użyć

std::lock_guard<std::mutex> lock(mutex);

jeśli nie chcesz korzystać z biblioteki Boost.

Powiązane problemy