标签:访问级别 cond second join() 操作 ret oid return 定义
线程中的锁分为两种,互斥锁和共享锁。
相关的头文件有<mutex>
,<shared_mutex>
,前者具有std::unique_lock
操作,用于实现互斥功能,后者具有std::shared_lock
操作,用于完成共享锁操作。
这里先讨论std::shared_mutex
这个类。
如果需要使用共享锁,则需要使用到std::shared_mutex
这个类。具体讲解见这里
该锁可用于保护被多个线程同时访问的共享数据。
std::shared_mutex
有两种访问级别:
如果一个线程已经获取了互斥锁,则其他线程都无法获取该锁。
如果一个线程已经获取了共享锁,则其他任何线程都无法获取互斥锁,但是可以获取共享锁。
说到这里,为了实现该锁的互斥和共享,不得不介绍std::shared_lock
和std::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
从这个输出可以看出:
如果一个线程已经获取了共享锁,则其他任何线程都无法获取互斥锁,但是可以获取共享锁。
从这个输出可以看出,验证了如果一个线程已经获取了互斥锁,则其他线程都无法获取该锁。
标签:访问级别 cond second join() 操作 ret oid return 定义
原文地址:https://www.cnblogs.com/fenghualong/p/11568398.html