作者adrianshum (Alien)
看板C_and_CPP
标题Re: [问题] singleton pattern for multithread
时间Fri Jul 3 18:59:31 2009
※ 引述《su31o4gj83 (哈哈哈哈哈哈哈哈哈哈哈)》之铭言:
[43
: 其中提到
:
: For the following case:
:
: pInstance_ = new WindowManager();
:
: the compiler allocates space for WindowManager object, calls the constructor
: and initializes pInstance_. It's quite possible that the optimizer moves
: around instructions so that pInstance_ is initialized before the object has
: been completely initialized. This may cause some other thread calling
: getInstance() to return partially initialzed object.
:
[43]
: 推 legnaleurc:有啊,内文不就说最佳化後有可能让pI在WM前初始化完成 07/03 17:31
: → su31o4gj83:l大, 我不太了解multithread, 为什麽多执行绪会让 07/03 17:42
: → su31o4gj83:pI在WM前初始化完成??一般的编程一定是singlethread吗 07/03 17:48
: → su31o4gj83:new某个物件new到一半就不做了, 让我有点难以接受阿XD 07/03 17:52
不是不做, 而是事件的先後发生顺序分别罢了.
他说的 "可能" 的发生顺序是这样:
1. 开始的时候, 只有一个 pInstance ptr
[pInstance]
2. allocate 一块 memory, 里面还是未初始的
[pInstance] +----------+
| #$$%&^%* |
| (*&^*&^# |
+----------+
3. pInstance 先指向那片 memory
+----------+
| #$$%&^%* |
[pInstance]------->| (*&^*&^# |
+----------+
4. 初始化那片 memory
+----------+
| WindowMgr|
[pInstance]------->| |
+----------+
这一切, 如果在 single thread 发生的话, 什麽事都没有.
可是, 如果是multi-thread, 用文中那种 double-check-locking
的方法的话...
万一 Thread 1 在做上面的流程, 刚做到 3
Thread 2 进来 getInstance(), 一检查就发觉 pInstance not null
(为了 performance 考量, 是会先检查 null, 是 null 才去 acquire
mutex, 然後才再一次检查). 然後就拿着那 pInstance 来使用了.
假设到这刻 Thread1 还没有跑完 4, Thread2 就拿着 pInstance 用的
话, 就会出问题.
那并不是 new 到一半就不做.
当然, 整个故事的大前题是: compiler 真的会这样 optimize.
这个议题在 Java 其实有讨论过很多次, 而 Java Compiler 也真
的会这样 optimize.
但问题是, 是不是真的有 C++ compiler 会这样 optimize?
至少这样的 double check lazy instantiation 做法,
在 C++ 界行之有年, 也没有听过有什麽惨况.
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 202.155.236.82
1F:推 wowtiger:会不会是相反... new 出来还没办放到 instance 里面 07/04 16:03
2F:→ wowtiger:另一个以为还没有就有 new 一份 ... 结果 instance 乱掉 07/04 16:04
3F:推 Ebergies:相反不就是预期中会发生的事吗? lol 07/04 22:01