关于双重if的妙用问题。大家一起讨论讨论。。

亥尚 2014-01-16 10:41:17
今天在看书的时候看的这个问题。希望大家一起思考一下,代码如下:

volatile T* pInst = 0;
T* GetInstance()
{
if(pInst == NULL)
{
lock();
if(pInst == NULL)
pInst = new T;
unlock();
}
return pInst;
}

书上说,双重if在这里另有妙用,可以让lock的调用开销降低到最小。求解。。。考虑不出来啊。

可以先不用CPU乱序执行会打乱new那一句的执行,抛开逻辑,只看双重if。
...全文
589 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
YTerrenceLau 2014-01-17
  • 打赏
  • 举报
回复
结贴吧,20分给5楼,2楼3楼10楼瓜分剩下的20分。 典型的double check实现单例模式。 不过这里即使用了double check,仍然有bug。
modyaj 2014-01-17
  • 打赏
  • 举报
回复
他是想保证每次分配空间时候都上锁 不分配的时候就别上锁了 节约点
  • 打赏
  • 举报
回复
正解: 这个完全不需要有个“双重if”这么个专有名字,就是一种必要的写法而已。 关键的是里面的if,无论如何不能舍弃。否则可能创建多份实例。外边的if在实例已经创建的时候避免操作锁,提高了效率。 一步步分析如下: if != NULL { lock new unlock } 有bug,多线程的bug,可能多次new lock if != NULL new unlock 没有多次new的bug,但是有效率问题,每次都要lock一次 if != NULL { lock if != NULL new unlock } 所谓“双重if”,避免了上边的问题 ps:各种高屋建瓴者能否消失?
赵4老师 2014-01-16
  • 打赏
  • 举报
回复
参考lock的源代码。
漫步者、 2014-01-16
  • 打赏
  • 举报
回复
遇到了线程,乱成一锅粥
mujiok2003 2014-01-16
  • 打赏
  • 举报
回复
c++ 11也可以直接使用std::call_once
mujiok2003 2014-01-16
  • 打赏
  • 举报
回复
在c++ 11中下面的实现是线程安全的.

T* GetInstance()
{ 
    static  T* pInst = new T;   
    return pInst;
}
mujiok2003 2014-01-16
  • 打赏
  • 举报
回复
double check lock
volatile T* pInst = 0;
T* GetInstance()
{
    if(pInst == NULL)
    {
        lock();
        if(pInst == NULL)
            pInst = new T;
        unlock();
    }
    return pInst;
}
相对于直接lock高效.
volatile T* pInst = 0;
T* GetInstance()
{
//    if(pInst == NULL)
 {
        lock();
        if(pInst == NULL)
            pInst = new T;
        unlock();
    }
    return pInst;
}
赵4老师 2014-01-16
  • 打赏
  • 举报
回复
对每句C代码执行时对应的汇编指令集胸有成竹。
肖邦之离歌 2014-01-16
  • 打赏
  • 举报
回复
首先说你这个是单例设计模式,并且考虑到使用多线程的安全性(加锁)。 单例模式的作用就是使该类对象在程序运行始末至多只有一个对象。 这里假设同时有两个线程A、B来访问GetInstance(),A和B同时执行第一个判断语句,结果一样,都进入了代码块,然后A、B又要lock(),但是lock()的设定就是只允许一个线程进入。假设A进入了,B在等待。 A进入后首先判断是不是NULL,也是成功进入代码块,也就是说new了一个对象。然后解锁返回对象。 唤醒B,这是B进入发现第二个判断通过不了(因为A已经new了一个对象)。这样的话B就直接解锁返回对象。 假设只有最外层的判断的话,那么B也会创建一个对象。这样的话就有两个对象在内存中了。
www_adintr_com 2014-01-16
  • 打赏
  • 举报
回复
这个肯定涉及到多线程了,单线程根本就不需要 lock 这些。 在多线程的环境下,外面一个 if 使得绝大多数情况下都不会调用 lock/unlock 函数,当然就提高效率了。 lock()/unlock() 之间还需要使用一个 if 是保证了正确性,在执行 lock() 的过程中,可能其他线程修改了 pInst 变量。需要重新判断一次。
亥尚 2014-01-16
  • 打赏
  • 举报
回复
自己先顶一个、、、

15,440

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧