一、多线程之高效的读写锁:shared_mutex
允许线程获取多个共享所有权和一个专享权,实现了读写锁的机制,即多个读线程,一个写线程。
#include <iostream>
#include <map>
#include <string>
#include <mutex>
#include <shared_mutex>
#include <future>
//#include <boost/thread/shared_mutex.hpp>
class dns_entry
{};
class dns_cache
{
std::map<std::string, dns_entry> entries;
std::shared_mutex entry_mutex;
public:
dns_entry find_entry(std::string const& domain)
{
std::shared_lock<std::shared_mutex> lk(entry_mutex);
std::cout << "进入读锁!\n";
std::this_thread::sleep_for(std::chrono::milliseconds(10));
std::map<std::string, dns_entry>::const_iterator const it =
entries.find(domain);
dns_entry entrie = (it == entries.end()) ? dns_entry() : it->second;
std::cout << "退出读锁!\n";
return entrie;
}
void update_or_add_entry(std::string const& domain,
dns_entry const& dns_details)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::lock_guard<std::shared_mutex> lk(entry_mutex);
std::cout << "进入写锁!\n";
std::this_thread::sleep_for(std::chrono::milliseconds(100));
entries[domain] = dns_details;
std::cout << "退出写锁!\n";
}
};
int main()
{
dns_cache CC;
std::future<dns_entry> reader0 = std::async(std::launch::async, &dns_cache::find_entry, &CC, "qwruqi");
std::future<void> reader1 = std::async(std::launch::async, std::bind(&dns_cache::update_or_add_entry, &CC, "q", dns_entry()));
std::future<dns_entry> reader2 = std::async(std::launch::async, &dns_cache::find_entry, &CC,"q3");
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::future<dns_entry> reader3 = std::async(std::launch::async, &dns_cache::find_entry, &CC, "q12");
}
二、测试说明代码
1、打印结果:
进入读锁!
进入读锁!
退出读锁!
退出读锁!
进入写锁!
退出写锁!
进入读锁!
退出读锁!
打印解释(调用sleep_for是为了达到测试效果):
1)“进入写锁!"和“退出写锁!”之间一定不会有关于读锁的打印。因为一旦进入写线程,“写锁”专项所有权,必须要等写线程释放锁,其他线程才能进入。
2)“进入读锁!"和与之匹配的“退出读锁!”之间一定不会包含关于写锁的打印,因为读已经拿到锁,写为专项所有权,就必须等读释放说才能拿到锁。
3)“进入读锁!”和与之匹配的“退出读锁!”之间可以有关于其他其他读锁的打印,因为读是共享的。
如有错误或不足欢迎评论指出!创作不易,转载请注明出处。如有帮助,记得点赞关注哦(⊙o⊙)
更多内容请关注个人博客:https://blog.csdn.net/qq_43148810