c++lock詳解

一、c lock作用

c++lock是一種線程同步機制,用於保護共享資源的訪問。在多線程環境下,如果多個線程同時訪問了同一份數據,就會導致數據不一致的問題。通過使用c++lock,我們可以保證同一時間只有一個線程能夠訪問共享資源,從而避免了數據不一致的問題。

二、c lock用法

c++lock的用法非常簡單。我們只需要在訪問共享資源之前,通過lock()函數鎖定共享資源,訪問完成後再通過unlock()函數釋放鎖即可。下面是一段示例代碼:

#include
#include
#include

using namespace std;

int g_num = 0; // 共享資源
mutex g_mutex; // 鎖對象

void func()
{
    // 鎖定共享資源
    g_mutex.lock();
    
    // 訪問共享資源
    cout << "Thread ID: " << this_thread::get_id() < " << ++g_num << endl;
    
    // 釋放鎖
    g_mutex.unlock();
}

int main()
{
    thread t1(func);
    thread t2(func);
    
    t1.join();
    t2.join();
    
    return 0;
}

三、c lock 參數

c++lock有3種不同的鎖類型:unique_lock、lock_guard和defer_lock。其中unique_lock是最靈活的一種,支持鎖定和解鎖多次,而lock_guard則是最簡單的一種,只支持一次性鎖定。defer_lock則是延遲鎖定,即先不鎖定,等到需要訪問共享資源時再鎖定。下面是一段使用defer_lock參數的示例代碼:

#include
#include
#include

using namespace std;

int g_num = 0; // 共享資源
mutex g_mutex; // 鎖對象

void func()
{
    // 延遲鎖定
    unique_lock lock(g_mutex, defer_lock);
    
    // 訪問共享資源前先鎖定
    lock.lock();
    
    // 訪問共享資源
    cout << "Thread ID: " << this_thread::get_id() < " << ++g_num << endl;
    
    // 解鎖
    lock.unlock();
}

int main()
{
    thread t1(func);
    thread t2(func);
    
    t1.join();
    t2.join();
    
    return 0;
}

四、c lock this

c++lock使用this鎖定時,需要注意避免出現多線程死鎖的問題。如果在一個函數中多次鎖定this指針,就會出現死鎖的問題。下面是一段可能導致死鎖的示例代碼:

#include
#include
#include

using namespace std;

class Test
{
public:
    Test() : m_num(0) {}
    
    void func()
    {
        // 第一次鎖定this指針
        m_mutex.lock();
        
        // 第二次鎖定this指針,會導致死鎖
        this->m_mutex.lock();
        
        // 訪問共享資源
        cout << "Thread ID: " << this_thread::get_id() < " << ++m_num << endl;
        
        // 解鎖
        m_mutex.unlock();
    }
    
private:
    int m_num; // 共享資源
    mutex m_mutex; // 鎖對象
};

int main()
{
    Test t;
    thread t1(&Test::func, &t);
    thread t2(&Test::func, &t);
    
    t1.join();
    t2.join();
    
    return 0;
}

五、c lock 無效

c++lock可能會無效的一種情況是,不同線程使用了不同的mutex對象。因為不同的mutex對象無法鎖定同一個共享資源,所以c++lock就會無效。下面是一段可能導致c++lock無效的示例代碼:

#include
#include
#include

using namespace std;

int g_num = 0; // 共享資源
mutex g_mutex1; // 鎖對象1
mutex g_mutex2; // 鎖對象2

void func()
{
    // 使用了不同的mutex對象,無法鎖定同一份共享資源
    unique_lock lock(g_mutex1);
    
    // 訪問共享資源
    cout << "Thread ID: " << this_thread::get_id() < " << ++g_num << endl;
    
    // 解鎖
    lock.unlock();
}

int main()
{
    thread t1(func);
    thread t2(func);
    
    t1.join();
    t2.join();
    
    return 0;
}

六、c lock 參數要求

c++lock對鎖對象的要求非常嚴格,必須保證所有訪問共享資源的線程都使用同一份mutex對象。否則就會出現線程競爭的問題,導致數據不一致。下面是一段使用了不同mutex對象的示例代碼:

#include
#include
#include

using namespace std;

int g_num = 0; // 共享資源
mutex g_mutex1; // 鎖對象1
mutex g_mutex2; // 鎖對象2

void func1()
{
    // 使用了不同的mutex對象,會導致線程競爭問題
    unique_lock lock(g_mutex1);
    
    // 訪問共享資源
    cout << "Thread ID: " << this_thread::get_id() < " << ++g_num << endl;
    
    // 解鎖
    lock.unlock();
}

void func2()
{
    // 使用了不同的mutex對象,會導致線程競爭問題
    unique_lock lock(g_mutex2);
    
    // 訪問共享資源
    cout << "Thread ID: " << this_thread::get_id() < " << ++g_num << endl;
    
    // 解鎖
    lock.unlock();
}

int main()
{
    thread t1(func1);
    thread t2(func2);
    
    t1.join();
    t2.join();
    
    return 0;
}

七、clock

c++中的clock函數用於測量程序運行的時間。clock函數返回從程序開始運行起,處理器時鐘所需的時間(以時鐘周期為單位)。下面是一段使用clock函數測量程序運行時間的示例代碼:

#include
#include

using namespace std;

int main()
{
    clock_t start_time = clock(); // 記錄程序開始時間

    // 執行代碼段
    for(int i=0; i<10000000; i++);
    
    clock_t end_time = clock(); // 記錄程序結束時間
    double total_time = static_cast(end_time - start_time) / CLOCKS_PER_SEC; // 計算總時間
    
    cout << "程序運行時間:" << total_time << " 秒" << endl;
    
    return 0;
}

八、cblock

c++中的cblock語法和c++lock非常相似,都用於保護共享資源。cblock語法本質上是一種代碼塊,可以在代碼塊前後使用宏定義來自動加鎖和解鎖。下面是一段使用cblock保護共享資源的示例代碼:

#include
#include
#include

using namespace std;

int g_num = 0; // 共享資源
mutex g_mutex; // 鎖對象

#define C_BLOCK(mutex) for(unique_lock lock(mutex); true; lock.unlock()) // 宏定義,用於加鎖和解鎖

void func()
{
    C_BLOCK(g_mutex)
    {
        // 訪問共享資源
        cout << "Thread ID: " << this_thread::get_id() < " << ++g_num << endl;
    }
}

int main()
{
    thread t1(func);
    thread t2(func);
    
    t1.join();
    t2.join();
    
    return 0;
}

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/296067.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-27 12:57
下一篇 2024-12-27 12:57

相關推薦

  • Python Lock RLock用法介紹

    本文將從以下幾個方面對Python Lock RLock進行詳細的闡述:概念介紹、實例應用、區別比較、使用注意事項和常見問題解決。 一、概念介紹 Lock和RLock是Python…

    編程 2025-04-27
  • Linux sync詳解

    一、sync概述 sync是Linux中一個非常重要的命令,它可以將文件系統緩存中的內容,強制寫入磁碟中。在執行sync之前,所有的文件系統更新將不會立即寫入磁碟,而是先緩存在內存…

    編程 2025-04-25
  • 神經網路代碼詳解

    神經網路作為一種人工智慧技術,被廣泛應用於語音識別、圖像識別、自然語言處理等領域。而神經網路的模型編寫,離不開代碼。本文將從多個方面詳細闡述神經網路模型編寫的代碼技術。 一、神經網…

    編程 2025-04-25
  • Java BigDecimal 精度詳解

    一、基礎概念 Java BigDecimal 是一個用於高精度計算的類。普通的 double 或 float 類型只能精確表示有限的數字,而對於需要高精度計算的場景,BigDeci…

    編程 2025-04-25
  • Python安裝OS庫詳解

    一、OS簡介 OS庫是Python標準庫的一部分,它提供了跨平台的操作系統功能,使得Python可以進行文件操作、進程管理、環境變數讀取等系統級操作。 OS庫中包含了大量的文件和目…

    編程 2025-04-25
  • git config user.name的詳解

    一、為什麼要使用git config user.name? git是一個非常流行的分散式版本控制系統,很多程序員都會用到它。在使用git commit提交代碼時,需要記錄commi…

    編程 2025-04-25
  • Linux修改文件名命令詳解

    在Linux系統中,修改文件名是一個很常見的操作。Linux提供了多種方式來修改文件名,這篇文章將介紹Linux修改文件名的詳細操作。 一、mv命令 mv命令是Linux下的常用命…

    編程 2025-04-25
  • MPU6050工作原理詳解

    一、什麼是MPU6050 MPU6050是一種六軸慣性感測器,能夠同時測量加速度和角速度。它由三個感測器組成:一個三軸加速度計和一個三軸陀螺儀。這個組合提供了非常精細的姿態解算,其…

    編程 2025-04-25
  • Python輸入輸出詳解

    一、文件讀寫 Python中文件的讀寫操作是必不可少的基本技能之一。讀寫文件分別使用open()函數中的’r’和’w’參數,讀取文件…

    編程 2025-04-25
  • nginx與apache應用開發詳解

    一、概述 nginx和apache都是常見的web伺服器。nginx是一個高性能的反向代理web伺服器,將負載均衡和緩存集成在了一起,可以動靜分離。apache是一個可擴展的web…

    編程 2025-04-25

發表回復

登錄後才能評論