我是靠谱客的博主 细心帽子,最近开发中收集的这篇文章主要介绍c++11并发编程历程(10)锁定在恰当的粒度,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

锁粒度用来描述单个锁所保护的数据量。细粒度保护着少量的数据,粗粒度保护着大量的数据。

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)锁定在恰当的粒度所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部