[C++11 并发编程] 10 - 对极少修改的数据进行保护
来源:互联网 发布:ise女装官网淘宝网 编辑:程序博客网 时间:2024/06/09 20:35
假设有一个用于进行域名解析的DNS缓存数据,在大多数情况下,DNS数据很少会改变。当用户访问新的网站时,新的DNS信息才会被自动添加到这个转换表之中。虽然对这个数据的修改很少发生,但是在多个线程读取数据时,有线程要修改数据,仍然会导致读取线程读到错误的数据。我们需要使用某种方式来对读写操作进行保护。
使用前面几节用到的std::mutex可以达到保护数据完整性的效果,但是效率太低。因为大多数线程都是读取数据而不是修改数据,使用mutex,就会导致读取数据操作被认为的串行化,而降低多线程程序的执行效率。“读-写锁”则比较适合用在这里,读操作可以同时进行,而在进行写操作时,其它的读操作会被挂起。
C++标准库不支持这样的读写锁,这里用Boost库中的boost::shared_mutex来作为例子。与使用std::mutex的方法类似,我们可以使用std::lock_guard<boost::shared_mutex>和std::unique_lock<boost::shared_mutex>来进行枷锁操作,以保证操作时互斥的。对于只是读取而不修改数据的线程,则使用boost::shared_lock<boost::shared_mutex>来对数据进行共享访问。
#include <map>#include <string>#include <mutex>#include <boost/thread/shared_mutex.hpp>class dns_entry{};class dns_cache{ std::map<std::string,dns_entry> entries; boost::shared_mutex entry_mutex;public: dns_entry find_entry(std::string const& domain) {// 只读操作,使用boost::shared_lock<>来保护数据// 多个线程可以同时调用find_entry() boost::shared_lock<boost::shared_mutex> lk(entry_mutex); std::map<std::string,dns_entry>::const_iterator const it= entries.find(domain); return (it==entries.end())?dns_entry():it->second; } void update_or_add_entry(std::string const& domain, dns_entry const& dns_details) {// 更新操作,使用std::lock_guard<>来进行互斥保护// 只有一个线程可以进行更新操作,读取操作也会被block std::lock_guard<boost::shared_mutex> lk(entry_mutex); entries[domain]=dns_details; }};int main(){}
关于递归的加锁问题,如果在同一个线程的上下文对std::mutex进行多次加锁操作,其结果是不确定的。如果真的需要对一个mutex进行多次加锁操作,可以使用C++标准库提供的std::recursive_mutex。在同一个线程上下文中,可以对这种mutex进行多次加锁操作,加锁操作执行了多少次,解锁操作就需要做多少次,否则其它线程无法获取这个锁。使用std::lock_guard<std::recursive_mutex>和std::unique_lock<std:;recursive_mutex>可以帮助你解决这个问题。
实际上,我们并不建议使用递归锁。如果你发现你的代码中需要这种锁,最好先看看这样设计是否正确。因为mutex使用来进行进程间互斥的,同一个线程不需要对已经获得的锁再次进行加锁操作。
0 0
- [C++11 并发编程] 10 - 对极少修改的数据进行保护
- C++11 并发编程教程 - Part 2 : 保护共享数据
- 怎样对用户数据进行保护
- C++并发实战10:保护共享数据的可选机制
- c/c++面向对象编程之共用数据的保护
- C++多核高级编程 - 06 并发任务的通信和同步(2) 对并发进行同步
- 33.对学生结构体的数据进行修改
- PB对数据窗口的查询语句进行动态修改
- [C++11 并发编程] 09 - 在初始化阶段保护共享数据
- 3.对数据进行修改操作
- java里面在遍历集合的时候对集合进行添加或者删除修改时的并发修改异常
- linux 驱动对并发资源访问的保护
- 【Sqlserver】修改数据库表中的数据:对缺失的数据根据已有的数据进行修补
- 如何对dataset中进行修改并把修改后的数据保存到数据库中?
- 【C Prime Plus】学习笔记,Chapter 10,用const 修饰形参 保护数据,以防修改
- 对你的 REST API 进行保护的正确办法
- 如何对颈椎进行保护.
- 多线程中数据的并发访问与保护
- HDU 1997 汉诺塔VII(递归)
- 使用不带头结点的循环链表实现队列(数据结构)
- QTcpSocket 编程
- Linux 操作系统下如何优雅的卸载软件
- MySQL 插入数据时,中文乱码问题的解决
- [C++11 并发编程] 10 - 对极少修改的数据进行保护
- 《HTTP权威指南》阅读笔记(三)
- 静态链接库LIB和动态链接库DLL的区别
- Aapache: You don't have permission to access / on this server.错误
- UVA10087 Concatenation of Languages(字符hash)
- 集合栈
- 政府贷款扭曲生产(第一篇)
- C/C++中extern关键字详解
- Introduction to Java Programming编程题9.7<将字符串中的字符转换为数字>