C++11 멀티스레드-mutex(2)

5594 단어
C++11은 일반적인 mutex를 제공하는 토대에서 사용하기 쉬운 클래스도 제공했다. 이 부분에서 우리는 이 클래스들을 함께 볼 것이다.
1. lock_guard
lock_guard는 C++ RAII의 특성을 이용하여 구조 함수에 자물쇠를 채우고 분석 함수에서 자물쇠를 풀었다.lock_guard는 템플릿 클래스입니다. 원형은
template  class lock_guard

템플릿 매개 변수 Mutex는 상호 배율을 나타냅니다. 이전 설명서에서 설명한 std::mutex,std::timedmutex, std::recursive_mutex, std::recursive_timed_mutex 중 어느 것이든지 std::uniquelock (다음에 소개할 것) 은 모두 lock과 unlock의 능력을 제공합니다.lock_guard는 잠금, 잠금 해제에만 사용되며 mutex가 모든 생주기 관리를 맡지 않기 때문에 사용할 때lockguard가 관리하는 무텍스는 항상 유효합니다.다른 mutex 클래스와 마찬가지로locakguard는 복사를 허용하지 않습니다. 복사 구조와 값 부여 함수가 delete로 표시됩니다.
lock_guard(lock_guard const&) = delete;
lock_guard& operator=(lock_guard const&) = delete;

lock_guard의 디자인은 프로그램이 잠금 기간에 이상이 발생하더라도 안전하게 잠금을 풀고 사라진 잠금이 발생하지 않도록 보장한다.
#include 
#include 

std::mutex mutex;

void safe_thread() {
    try {
        std::lock_guard<:mutex> _guard(mutex);
        throw std::logic_error("logic error");
    } catch (std::exception &ex) {
        std::cerr << "[caught] " << ex.what() << std::endl;
    }
}
int main() {
    safe_thread();
    //       
    mutex.lock();
    std::cout << "OK, still locked" << std::endl;
    mutex.unlock();

    return 0;
}

프로그램 출력
[caught] logic error
OK, still locked

2. unique_lock
lock_guard는 간단한 자물쇠 잠금 해제 작업을 제공했지만, 우리가 더 유연한 조작을 필요로 할 때 무력해졌다.이것들은 유니크록이 나왔어.unique_lock은 Mutex에 대한 소유권을 가지고 있지만 unique 를 초기화합니다lock, 이 mutex를 인수하여 uniquelock가 생명주기가 끝나기 전(분석 전) 다른 곳에서는 이mutex를 직접 사용하지 마십시오.unique_lock에서 제공하는 기능이 비교적 많습니다. 여기는 일일이 열거하지 않고, 아래는 unique 을 열거합니다.lock의 클래스 성명 및 일부 주석을 참고하시기 바랍니다
template 
class unique_lock
{
public:
    typedef Mutex mutex_type;
    //  unique_lock  
    unique_lock() noexcept;
    //   m,    m.lock    ,  m        ,          。
    explicit unique_lock(mutex_type& m);
    //    m,       m  。         lock, try_lock, try_lock_xxx      。
    unique_lock(mutex_type& m, defer_lock_t) noexcept;
    //   m,    m.try_lock,             
    unique_lock(mutex_type& m, try_to_lock_t);
    //   m,      m         ,      。
    unique_lock(mutex_type& m, adopt_lock_t);
    //   m,    m.try_lock_unitil      
    template 
        unique_lock(mutex_type& m, const chrono::time_point& abs_time);
    //   m,   m.try_lock_for      
    template 
        unique_lock(mutex_type& m, const chrono::duration& rel_time);
    //   ,        (   adopt_lock_t    ),   mutex     ,   mutex
    ~unique_lock();

    //       
    unique_lock(unique_lock const&) = delete;
    unique_lock& operator=(unique_lock const&) = delete;

    //   move  
    unique_lock(unique_lock&& u) noexcept;
    unique_lock& operator=(unique_lock&& u) noexcept;

    void lock();
    bool try_lock();

    template 
        bool try_lock_for(const chrono::duration& rel_time);
    template 
        bool try_lock_until(const chrono::time_point& abs_time);

    //      ,      ,      lock        ,           
    void unlock();

    //     unique_lock     
    void swap(unique_lock& u) noexcept;
    //        mutex     ,      
    mutex_type* release() noexcept;

    //           
    bool owns_lock() const noexcept;
    //  owns_lock
    explicit operator bool () const noexcept;
    //   mutex  ,              
    //   :  mutex      unique_lock  ,     mutex    、    
    mutex_type* mutex() const noexcept;
};

3. std::call_once
이 함수의 작용은 말 그대로: 보증callonce에서 호출된 함수는 한 번만 실행됩니다.이 함수는 std::onceflag가 함께 사용됩니다.std::once_flag는 대외적으로 폐쇄된 것으로 설계되었다. 즉, 외부에 어떤 경로도 바꿀 수 없는onceflag의 값은 std:::call 을 통해서만 가능합니다.once 함수 수정.일반적인 상황에서 우리는 스스로 캐럴을 실현한다once 효과는 전역 변수와 이중 검사 자물쇠 (DCL) 를 사용해서 이루어지는데, 그래도 많은 구멍이 있을 수 있다.관심 있는 독자는 DCL을 검색해 보십시오. 여기서는 더 이상 군말하지 않습니다.C++11은 우리에게 간편한 해결 방안을 제공했고 필요한 것은 아래와 같이 사용하면 된다.
#include 
#include 
#include 

void initialize() {
    std::cout << __FUNCTION__ << std::endl;
}

std::once_flag of;
void my_thread() {
    std::call_once(of, initialize);
}

int main() {
    std::thread threads[10];
    for (std::thread &thr: threads) {
        thr = std::thread(my_thread);
    }
    for (std::thread &thr: threads) {
        thr.join();
    }
    return 0;
}
//      :initialize

4. std::try_lock
mutex가 여러 개 있으면trylock에서 이 함수는 간편한 조작을 제공합니다.try_lock는 매개 변수의 왼쪽에서 오른쪽으로 순서대로try 를 실행합니다lock 작업그중의 어떤 mutex가try_lock 실패 (false로 되돌아오거나 이상을 던질 때) 잠긴 mutex는 잠금 해제됩니다.주의해야 할 것은 이 함수가 성공할 때 -1을 되돌려줍니다. 그렇지 않으면 실패한 mutex의 인덱스를 되돌려줍니다. 인덱스는 0에서 계수를 시작합니다.
template 
  int try_lock(L1&, L2&, L3&...);

5. std::lock
std::lock은 비교적 스마트한 대량 잠금 방식으로 잠금 알고리즘을 사용하여 주어진mutex 목록을 잠그고 잠금을 피합니다.이 함수는mutex 목록의 잠금 순서에 대해 확실하지 않습니다.이 함수는 성공하면 모든mutex가 잠기고 실패하면 모두 잠금을 해제합니다.
template 
  void lock(L1&, L2&, L3&...);

이전 C++11 멀티스레드-mutex(1)
카탈로그
다음 C++11 멀티스레드 - 조건 변수

좋은 웹페이지 즐겨찾기