C++關於鎖的總結(一)


C++關於鎖的總結(一)

線程中的鎖分為兩種,互斥鎖共享鎖

相關的頭文件有<mutex><shared_mutex>,前者具有std::unique_lock操作,用於實現互斥功能,后者具有std::shared_lock操作,用於完成共享鎖操作。

這里先討論std::shared_mutex這個類。

共享鎖

如果需要使用共享鎖,則需要使用到std::shared_mutex這個類。具體講解見這里

該鎖可用於保護被多個線程同時訪問的共享數據。

std::shared_mutex有兩種訪問級別:

  • 共享:多個線程可以共享這個鎖的擁有權。一般用於數據的讀操作,防止數據被寫修改。
  • 互斥:僅僅一個線程可以擁有這個鎖。一般用於寫操作。

如果一個線程已經獲取了互斥鎖,則其他線程都無法獲取該鎖。
如果一個線程已經獲取了共享鎖,則其他任何線程都無法獲取互斥鎖,但是可以獲取共享鎖

說到這里,為了實現該鎖的互斥和共享,不得不介紹std::shared_lockstd::unique_lock這兩個模板。前者定義在<shared_mutex>,后着定義在<mutex>中。

在下面的代碼中均以測試過,編譯選項為--std=c++1z -pthread;

由於c++中的cout不是線程安全的函數,所以給cout輸出加上了互斥鎖。

共享鎖的代碼示例

#include <shared_mutex>
#include <mutex>
#include <iostream>
#include <thread>
#include <chrono>

std::shared_mutex test_lock;

std::mutex cout_lock;

int arr[3] = {11, 22, 33};

void unique_lock_demo(int id)
{
    std::unique_lock lock{test_lock};

    for(int i =0; i < 3; i++)
    {
            arr[i] = i + 100 * id;
    }

    for(int i = 0; i < 3; i++)
    {
        std::unique_lock pl(cout_lock);
        std::cout << "In unique: " << id << ": " << arr[i] << std::endl;
        pl.unlock();
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}


void shared_lock_demo(int id)
{
    std::shared_lock lock{test_lock};

    for(int i = 0; i < 3; i++)
    {
        std::unique_lock pl(cout_lock);
        std::cout << "In shared " << id << ": " << arr[i] << std::endl;
        pl.unlock();
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

int main()
{

   std::thread t3(unique_lock_demo,3);
   std::thread t4(unique_lock_demo,4);
   std::thread t1(shared_lock_demo,1);
   std::thread t2(shared_lock_demo,2);

   t1.join();
   t2.join();
   t3.join();
   t4.join();
   return 0;
}

輸出為:

In unique: 3: 300
In unique: 3: 301
In unique: 3: 302
In shared 1: 300
In shared 2: 300
In shared 1: 301
In shared 2: 301
In shared 1: 302
In shared 2: 302
In unique: 4: 400
In unique: 4: 401
In unique: 4: 402

從這個輸出可以看出:

  • 如果一個線程已經獲取了共享鎖,則其他任何線程都無法獲取互斥鎖,但是可以獲取共享鎖

  • 從這個輸出可以看出,驗證了如果一個線程已經獲取了互斥鎖,則其他線程都無法獲取該鎖。

注:關於上述代碼有的平台運行不了,可以運行下面的代碼


#include <shared_mutex>
#include <mutex>
#include <iostream>
#include <thread>
#include <chrono>

std::shared_mutex test_lock;

std::mutex cout_lock;

int arr[3] = {11, 22, 33};

void unique_lock_demo(int id)
{
    std::unique_lock<std::shared_mutex> lock(test_lock);

    for(int i =0; i < 3; i++)
    {
            arr[i] = i + 100 * id;
    }

    for(int i = 0; i < 3; i++)
    {
        std::unique_lock<std::mutex> pl(cout_lock);
        std::cout << "In unique: " << id << ": " << arr[i] << std::endl;
        pl.unlock();
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}


void shared_lock_demo(int id)
{
    std::shared_lock<std::shared_mutex> lock(test_lock);

    for(int i = 0; i < 3; i++)
    {
        std::unique_lock<std::mutex> pl(cout_lock);
        std::cout << "In shared " << id << ": " << arr[i] << std::endl;
        pl.unlock();
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

int main()
{

   std::thread t3(unique_lock_demo,3);
   std::thread t1(shared_lock_demo,1);
   std::thread t2(shared_lock_demo,2);
   std::this_thread::sleep_for(std::chrono::seconds(4));
   std::thread t4(unique_lock_demo,4);

   t1.join();
   t2.join();
   t3.join();
   t4.join();
   return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM