如果多线程访问的数据在大部分时刻都是被读,只有极少的几率被写,那么如果使用mutex可能会导致效率低下。但是C++11并没有相应的手段,尽管一种方案被提交给C++委员会,但是没有通过。它就是boost::shared_mutex,它不是灵丹妙药,而且他的效率依赖于计算机的核数以及线程处理的工作量。对于超大规模的系统来说,它是具有实在的益处的。
对于需要做数据更新操作的线程,可以使用lock_guard<boost::shared_mutex>或unique_lock<boost::shared_mutex>来独占mutex;而只读线程则可以使用 boost::shared_lock<boost::shared_mutex>,此时多个线程可以在同一时刻共享同一个boost::shared_lock,也就是同时锁定这个mutex。唯一的限制是:当有线程使用boost::shared_lock<boost::shared_mutex>占有mutex时,那么一个线程想请求一个独占锁来更新数据就只能阻塞,知道所有其他的共享锁都被放弃后才能获取独占锁。相对应的,只要有一个线程独占mutex,那么其他线程的所有对mutex的共享、独占请求都将进入阻塞状态。
下面的程序演示了一个模拟DNS服务器映射的管理过程:
class dns_entry;
class dns_cache
{
std::map<std::string, dns_entry> entries;
mutable boost::shared_mutex entry_mutex;
public:
dns_entry find_entry(std::string const& domain) const
{
boost::shared_lock<boost::shared_mutex> lk(entry_mutex);
auto 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;
}
};