概述
锁粒度用来描述单个锁所保护的数据量。细粒度保护着少量的数据,粗粒度保护着大量的数据。
void get_and_process_data()
{
std::unique_lock<std::mutex> my_lock(the_mutex);
some_class data_to_process = get_next_data_chunk();
my_lock.unlock(); //在对process()的调用中不需要互斥元
result_type result = process(data_to_process);
my_lock.lock(); //重新锁定互斥元
write_result(data_to_process,result);
}
上面的锁定与解锁也可以换成如下写法:
std::unlock(my_lock);
std::lock(my_lock);
一般情况下,只应该以执行要求的操作所需最小可能时间去持有锁。
如果需要锁定两个互斥锁的操作是交换操作,这显然需要并发访问两个对象,假设你试图去比较的仅为普通int的简单数据成员,int可以很容易复制,所以可以很容易地为每个待比较的对象复制其数据,同时只用持有原对象的锁,然后去比较复制值。这样就不会在比较的过程中还一直所锁定着保护原对象的互斥元。
class Y
{
private:
int some_detail;
mutable std::mutex m;
int get_detail() const
{
std::lock_guard<std::mutex> lock_a(m);
return some_detail;
}
public:
Y(int sd):some_detail(sd){}
friend bool operator == (Y const& lhs,Y const& rhs)
{
if(&lhs==&rhs)
return true;
int const lhs_detail = lhs.get_detail(); //①
int const rhs_detail = rhs.get_detail(); //②
return lhs_detail == rhs_detail;
}
}
get_detail()返回的是some_detail的复制品,所以就不用一直锁着保护some_detail的互斥元m。
但是如果在①和②之间值进行了变化(比如交换等等),这样的比较就变得毫无意义了。如果不能在操作的整个持续时间内持有锁,就会将自己暴露在竞争中。
最后
以上就是细心帽子为你收集整理的c++11并发编程历程(10)锁定在恰当的粒度的全部内容,希望文章能够帮你解决c++11并发编程历程(10)锁定在恰当的粒度所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复