设为首页 加入收藏

TOP

《C++并发编程实战》读书笔记(2):线程间共享数据(二)
2023-09-09 10:25:33 】 浏览:117
Tags:程实战 程间共
resource> resource_ptr; std::once_flag resource_flag; void init_resource() { resource_ptr.reset(new some_resource); } void foo() { std::call_once(resource_flag, init_resource); resource_ptr->do_something(); }

C++11规定了局部静态变量的初始化只会在某个单一线程上发生,在初始化完成之前,其它线程不会越过静态数据的声明而继续运行。如果某些类只需要用到唯一一个全局实例,这种情况下可以用以下方法代替std::call_once

class my_class;
my_class& get_my_class_instance()
{
    static my_class instance;
    return instance;
}

3.2、保护不常更新的数据

如果我们想要允许单独一个“写线程”进行完全排他的访问,也允许多个“读线程”共享数据或并发访问,那么可以使用C++17提供的新互斥量std::shared_mutex。对于更新操作,使用std::lock_guard<std::shared_mutex>std::unique_lock<std::shared_mutex>锁定,代替对应的std::mutex特化,它们都保证了访问的排他性质。对于无需更新数据结构的线程,可以另行改用共享锁std::shared_lock<std::shared_mutex>,多个线程能够同时锁住同一个std::shared_mutex

class dns_entry {};

class dns_cache
{
    std::map<std::string, dns_entry> entries;
    std::shared_mutex entry_mutex;
public:
    dns_entry find_entry(const std::string& domain)
    {
        std::shared_lock<std::shared_mutex> lk(entry_mutex);
        auto it = entries.find(domain);
        return it == entries.end() ? dns_entry() : it->second;
    }
    void update_or_add_entry(const std::string& domain, const dns_entry& dns_details)
    {
        std::lock_guard<std::shared_mutex> lk(entry_mutex);
        entries[domain] = dns_details;
    }
};

3.3、递归加锁

标准库提供了std::recursive_mutex,其工作方式与std::mutex相似,不同之处是其允许同一线程对某互斥量的同一实例多次加锁。假如我们对它调用3次lock(),就必须调用3次unlock()才能解锁。

首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C++的编译链接与在vs中build提速 下一篇[C++] std::optional与RVO:最高..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目