Re: [問題] singleton pattern for multithread

看板C_and_CPP (C/C++)作者 (Alien)時間16年前 (2009/07/03 18:59), 編輯推噓2(201)
留言3則, 2人參與, 最新討論串2/2 (看更多)
※ 引述《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

07/04 16:03, , 1F
會不會是相反... new 出來還沒辦放到 instance 裡面
07/04 16:03, 1F

07/04 16:04, , 2F
另一個以為還沒有就有 new 一份 ... 結果 instance 亂掉
07/04 16:04, 2F

07/04 22:01, , 3F
相反不就是預期中會發生的事嗎? lol
07/04 22:01, 3F
文章代碼(AID): #1AJUIKX2 (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1AJUIKX2 (C_and_CPP)