• 为了异常安全(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++》

  • 相关阅读:
    document.body.clientHeight 和 document.documentElement.clientHeight 的区别
    Javascript操作div及其内含对象示例
    面向对象分析设计的经验原则
    翻页控件示例代码
    C#的6种常用集合类示例
    UML基础知识
    重温OSI和TCP/IP网络分层
    设计模式总结
    活用设计模式
    GridView当数据源为空时仍显示表头
  • 原文地址:https://www.cnblogs.com/Przz/p/6628896.html
Copyright © 2020-2023  润新知