天天看點

C++ 多線程:互斥對象 lock_gurad

描述

  • 頭檔案:​

    ​<mutex>​

  • 聲明方式: ​

    ​template< class Mutex > class lock_guard;​

  • 簡介

    ​​

    ​lock_guard​

    ​​是一種互斥包裝器,它提供了非常便捷的raii資源管控技術用來在對象生存周期内提供互斥鎖。

    ​​

    ​lock_gurad​

    ​​很好得解決了互斥變量​

    ​mutex​

    ​​的鎖成員在函數異常期間無法正常回收資源的問題。當lock_guard對象建立之時即嘗試擷取鎖的所有權,當該對象離開其所建立的作用域時會銷毀​

    ​lock_gurad​

    ​并釋放互斥變量的鎖。
PS:lock_guard 對象是不可指派的,它不支援指派運算符

成員函數

  • 構造函數​

    ​std::lock_guard<Mutex>::lock_guard​

  • ​explicit lock_guard( mutex_type& m ); (1)​

  • ​lock_guard( mutex_type& m, std::adopt_lock_t t ); (2)​

  • ​lock_guard( const lock_guard& ) = delete; (3)​

獲得給定的互斥變量所有權:

(1) 等效于調用m.lock()成員。若m不是遞歸鎖(即傳入位址),且目前線程已經占有m,則目前構造是未定義的

(2)獲得互斥m的所有權但并不調用lock進行鎖定,若目前線程不占有m,則構造是未定義的。

(3)不存在拷貝構造函數

如果m先于lock_guard被銷毀,則構造函數未定義

  • 析構函數​

    ​std::lock_guard<Mutex>::~lock_guard​

    ​​ 釋放所占有互斥的所有權。

    等效地調用 m.unlock() ,其中 m 是傳遞個 lock_guard 的構造函數的互斥。

使用案例如下:

#include <thread>
#include <mutex>
#include <iostream>
 
int g_i = 0;
std::mutex g_i_mutex;  // protects g_i
 
void safe_increment()
{
    std::lock_guard<std::mutex> lock(g_i_mutex);
    for (int i = 0;i < 10; ++i){

        ++g_i;
 
        std::cout << std::this_thread::get_id() << ": " << g_i << '\n';
    }
    // 當lock_guard離開目前作用域時mutex互斥量會自動釋放
}
 
int main()
{
    std::cout << "main: " << g_i << '\n';
 
    std::thread t1(safe_increment);
    std::thread t2(safe_increment);
 
    t1.join();
    t2.join();
 
    std::cout << "main: " << g_i << '\n';
}      
main: 0
0x700004de4000: 1
0x700004de4000: 2
0x700004de4000: 3
0x700004de4000: 4
0x700004de4000: 5
0x700004de4000: 6
0x700004de4000: 7
0x700004de4000: 8
0x700004de4000: 9
0x700004de4000: 10
0x700004e67000: 11
0x700004e67000: 12
0x700004e67000: 13
0x700004e67000: 14
0x700004e67000: 15
0x700004e67000: 16
0x700004e67000: 17
0x700004e67000: 18
0x700004e67000: 19
0x700004e67000: 20
main: 20      

總結

繼續閱讀