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

时间:2019-09-22
本文章向大家介绍C++关于锁的总结(一),主要包括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

从这个输出可以看出:

  • 如果一个线程已经获取了共享锁,则其他任何线程都无法获取互斥锁,但是可以获取共享锁

  • 从这个输出可以看出,验证了如果一个线程已经获取了互斥锁,则其他线程都无法获取该锁。

原文地址:https://www.cnblogs.com/fenghualong/p/11568398.html