假设有用户存储DNS条目缓存的表,支持多线程读取,但在进行更新时独占访问数据结构,直到它完成了操作。使用 std::mutex
来保护数据结构会在其没有修改时消除并发读取数据结构的可能。这种新的互斥元通常称为读写互斥元,因为它考虑了两种不同的用法:由单个“写”线程独占访问或共享,有多个“读”线程并发访问。
对于更新操作,std::lock_guard<boost::shared_mutex>
和 std::unique_lock<boost::shared_mutex>
可用于锁定,以取代相应的 std::mutex
特化,这确保了独占访问。那些不需要更新数据结构的线程能够转而使用 boost::shared_lock<boost::shared_mutex>
来获得共享访问,这与 std::unique_lock
用起来是相同的,除了多个线程在同一时间、统一 boost::share_mutex
上可能会有共享锁。唯一的限制是,如果任一线程拥有一个共享锁,试图独占锁的线程会被阻塞,直到其他线程全都撤回它们的锁;同样的,如果任一线程具有独占锁,其他线程都不能获取共享锁或独占锁,直到第一个线程撤回了它的锁。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| #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; mutable boost::shared_mutex entry_mutex; public: dns_entry entry(std::string const& domain) const { 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<boost::shared_mutex> lk(entry_mutex); entries[domain] = dns_details; } }
|