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;
}

原文链接: https://www.cnblogs.com/fenghualong/p/11568398.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    C++关于锁的总结(一)

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/303101

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月15日 下午11:56
下一篇 2023年2月15日 下午11:58

相关推荐