zoukankan      html  css  js  c++  java
  • 为了异常安全(swap,share_ptr)——Effecive C++

    互斥锁:

    假设我们要在多线程中实现背景图片的控制:

    class PrettyMenu{
    public:
        ……
        void changeBackground(std::istream& imgSrc);//改变背景图片
        ……
    private:
        Mutex mutex;    //互斥量
        Image* bgImage; //当前背景图片
        int imageChanges;   //背景图片改变次数
    };
    
    void PrettyMenu::changeBackground(std::istream& imgSrc)
    {
        lock(&mutex);
        delete bgImage;
        ++imageChanges;
        bgImage=new Image(imgSrc);
        unlock(&mutex);
    }
    

    但是上面这些会遇到两个问题:

    • 如果 new Image(imgSrc)发生了异常,那么unlock就不会被执行,会被一直锁住
    • 发生上面异常,imageChanges也被累加,但实际上新的图片没有被安装

    对于第一个问题:

    被及时释放的互斥锁:

    share_ptr我们可以指定它的删除器,所以可以在删除器中释放互斥锁.
    如此即使是发生了异常,互斥锁也能够被及时的释放。

    class Lock{
    public:
        explicit Lock(Mutex* mu):mutexPtr(mu,unlock)//以某个Mutex初始化,unlock作为删除其
        {
            lock(mutexPtr);
        }
    private:
        shared_prt<Mutex> mutexPtr;
    };
    

    如果通过一个Lock类,然后在析构函数阶段进行 unlock也可以避免这个问题。但是这样的类进行复制的时候
    可能存在很多不合理的问题。
    如果希望保存资源直到最后一个对象消失,并且在复制的时候是引用计数,可以使用上面这种情况。


    对于第二个问题:

    swap的 全or无:

    struct PMImpl{ 
        std::tr1::shared_ptr<Image> bgImage;
        int imageChanges;
    };
    class PrettyMenu{
        ……
    private:
        Mutex mutex;
        std::tr1::shared_ptr<PMImpl> pImpl;
    };
    
    void PrettyMenu::changeBackground(std::istream& imgSrc)
    {
        using std::swap;//**条款**25
        Lock m1(&mutex);
        std::tr1::shared_ptr<PMImpl> pNew(new PMImpl(*pImpl));
        pNew->bgImage.reset(new Image(imgSrc));;//修改副本
        ++pNew->imageChanges;
        swap(pImpl,pNew);
    }
    

    我们可以先弄一个副本,在进行完所有的操作之后,再与目标对象进行交换。
    从而实现: 要不然就不处理,不然就全部处理完。
    所以我们需要一个 不会抛出异常的swap操作。


    参考:

    《Effective C++》

  • 相关阅读:
    将截断字符串或二进制数据。语句已终止的解决方法
    201812-1 小明上学 Java
    201809-2 买菜 Java
    201809-1 卖菜 Java
    201803-2 碰撞的小球 Java
    201803-1 跳一跳 Java
    201712-2 游戏 Java
    201712-1 最小差值 Java
    201709-2 公共钥匙盒 Java
    201709-1 打酱油 Java
  • 原文地址:https://www.cnblogs.com/Przz/p/6628896.html
Copyright © 2011-2022 走看看