关于双重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。
...全文
759 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
  • 打赏
  • 举报
回复
自己先顶一个、、、
【更新至2025年】2001-2025年上市公司数字化转型年报词频统计(吴非、赵宸宇、甄红线)(300+年报词频统计) 1、时间:2001-2025年 2、来源:上市公司年报 3、参考文献:企业数字化转型与资本市场表现——来自股票流动性的经验证据(吴非) 数字化转型如何影响企业全要素生产率(赵宸宇) 知识产权行政保护与企业数字化转型(甄红线) 4、方法说明:(1)参考吴非老师的做法,对人工智能技术、大数据技术、云计算技术、区块链技术、数字技术运用五个维度76个数字化相关词频进行统计 (2)参考赵宸宇老师的做法,对数字技术应用、互联网商业模式、智能制造、现代信息系统四个维度99个数字化相关词频进行统计 (3)参考甄红线老师的做法,对技术分类、组织赋能、数字化应用等类别下139个数字化相关词频进行统计 5、指标:年份、股票代码、公司简称、行业名称、行业代码、全文-文本总长度、仅中英文-文本总长度、人工智能技术-吴、大数据技术-吴、云计算技术-吴、区块链技术-吴、数字技术运用-吴、数字技术应用-赵、互联网商业模式-赵、智能制造-赵、现代信息系统-赵、技术分类-人工智能技术-甄、技术分类-区块链技术-甄、技术分类-云计算技术-甄、技术分类-大数据技术-甄、组织赋能-人工智能技术-甄、组织赋能-云计算技术-甄、组织赋能-大数据技术-甄、组织赋能-广义数字技术-甄、数字化应用-技术创新-甄、数字化应用-流程创新-甄、数字化应用-业务创新-甄、人工智能、商业智能、图像理解、投资决策辅助系统、智能数据分析、智能机器人、机器学习、深度学习、语义搜索、生物识别技术、人脸识别、语音识别、身份验证、自动驾驶、自然语言处理、大数据、数据挖掘、文本挖掘、数据可视化、异构数据、征信、增强现实、混合现实、虚拟现实、云计算、流计算、图计算、内存计算、多方安全计算、类脑计算、绿色计算、认知计算等300+词频

15,446

社区成员

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

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