鍦ㄥ潡浣滅敤鍩熶腑鐨勯潤鎬佸彉閲忕殑瑙勫垯 (涓庝箣鐩稿鐨勬槸鍏ㄥ眬浣滅敤鍩熺殑闈欐佸彉閲? 鏄? 紼嬪簭絎竴嬈℃墽琛屽埌浠栫殑澹版槑鐨勬椂鍊欒繘琛屽垵濮嬪寲.

瀵熺湅涓嬮潰鐨勭珵浜夋潯浠?

int ComputeSomething()
{
   static int cachedResult = ComputeSomethingSlowly();
   return cachedResult;
}

榪欐浠g爜鐨勬剰鍥炬槸鍦ㄨ鍑芥暟絎竴嬈¤璋冪敤鐨勬椂鍊欏幓璁$畻涓浜涜垂鐢? 騫朵笖鎶婄粨鏋滅紦鍐茶搗鏉ュ緟鍑芥暟灝嗘潵鍐嶈璋冪敤鐨勬椂鍊欏垯鐩存帴榪斿洖榪欎釜鍊煎嵆鍙?

榪欎釜鍩烘湰鎶宸х殑鍙樼,鍦ㄧ綉緇滀笂涔熻鍙仛 閬垮厤 "static initialization order fiasco". ( fiasco榪欎釜璇?鍦ㄨ繖涓綉欏典笂鏈夐潪甯告鐨勬弿榪?鍥犳鎴戝緩璁ぇ瀹跺幓璇諱竴璇葷劧鍚庡幓鐞嗚В瀹?)

榪欐浠g爜鐨勯棶棰樻槸闈炵嚎紼嬪畨鍏ㄧ殑. 鍦ㄥ眬閮ㄤ綔鐢ㄥ煙涓殑闈欐佸彉閲忔槸緙栬瘧鏃朵細鍦ㄧ紪璇戝櫒鍐呴儴杞崲鎴愪笅闈㈢殑鏍峰瓙:

int ComputeSomething()
{
  static bool cachedResult_computed = false;
  static int cachedResult;
  if (!cachedResult_computed) {
     cachedResult_computed = true;
     cachedResult = ComputeSomethingSlowly();
  }
  return cachedResult;
}

鐜板湪绔炰簤鏉′歡灝辨瘮杈冨鏄撶湅鍒頒簡.

鍋囪涓や釜綰跨▼鍦ㄥ悓涓鏃跺埢閮借皟鐢ㄨ繖涓嚱鏁? 絎竴涓嚎紼嬪湪鎵ц cachedResult_computed = true 鍚? 琚姠鍗? 絎簩涓嚎紼嬬幇鍦ㄧ湅鍒扮殑 cachedResult_computed 鏄竴涓湡鍊? true ),鐒跺悗灝辯暐榪囦簡if鍒嗘敮鐨勫鐞?鏈鍚庤鍑芥暟榪斿洖鐨勬槸涓涓湭鍒濆鍖栫殑鍙橀噺.

鐜板湪浣犵湅鍒扮殑涓滆タ騫朵笉鏄竴涓紪璇戝櫒鐨刡ug, 榪欎釜琛屼負 C++ 鏍囧噯鎵瑕佹眰鐨?

浣犱篃鑳藉啓涓涓彉浣撴潵浜х敓涓涓洿緋熺硶鐨勯棶棰?

class Something { ... };
int ComputeSomething()
{
   static Something s;
   return s.ComputeIt();
}

鍚屾牱鐨勫湪緙栬瘧鍣ㄥ唴閮ㄥ畠浼氳閲嶅啓 (榪欐, 鎴戜滑浣跨敤C++浼唬鐮?:

class Something { ... };
int ComputeSomething()
{
  static bool s_constructed = false;
  static uninitialized Something s;
  if (!s_constructed) {
      s_constructed = true;
      new(&s) Something; // construct it
      atexit(DestructS);
  }
  return s.ComputeIt();
}
// Destruct s at process termination
void DestructS()
{
   ComputeSomething::s.~Something();
}

娉ㄦ剰榪欓噷鏈夊閲嶇殑绔炰簤鏉′歡. 灝卞儚鍓嶉潰鎵璇寸殑, 涓涓嚎紼嬪緢鍙兘鍦ㄥ彟涓涓嚎紼嬩箣鍓嶈繍琛屽茍涓斿湪"s"榪樻病鏈夎鏋勯犲墠灝變嬌鐢ㄥ畠.

鐢氳嚦鏇寸碂緋曠殑鎯呭喌, 絎竴涓嚎紼嬪緢鍙兘鍦╯_contructed 鏉′歡鍒ゅ畾 涔嬪悗,鍦ㄤ粬琚緗垚"true"涔嬪墠琚姠鍗? 鍦ㄨ繖縐嶅満鍚堜笅, 瀵硅薄s灝變細琚?span style="font-weight: bold;">鍙岄噸鏋勯?/span>鍜?span style="font-weight: bold;">鍙岄噸鏋愭瀯. 

榪欐牱灝變笉鏄緢濂?

浣嗘槸絳夌瓑, 榪欏茍涓嶆槸鍏ㄩ儴, 鐜板湪(鍘熸枃鏄疦ot,鎴戣涓烘槸Now鐨勭瑪璇?鐪嬬湅濡傛灉鏈?span style="font-style: italic;">涓や釜榪愯鏈熷垵濮嬪寲灞閮ㄩ潤鎬佸彉閲忕殑璇濅細鍙戠敓浠涔?

class Something { ... };
int ComputeSomething()
{
static Something s(0);
static Something t(1);
return s.ComputeIt() + t.ComputeIt();
}

涓婇潰鐨勪唬鐮佷細琚紪璇戝櫒杞寲涓轟笅闈㈢殑浼狢++浠g爜:

class Something { ... };
int ComputeSomething()
{
  static char constructed = 0;
static uninitialized Something s;
if (!(constructed & 1)) {
constructed |= 1;
new(&s) Something; // construct it
atexit(DestructS);
}
static uninitialized Something t;
if (!(constructed & 2)) {
constructed |= 2;
new(&t) Something; // construct it
atexit(DestructT);
}
return s.ComputeIt() + t.ComputeIt();
}

涓轟簡鑺傜渷絀洪棿, 緙栬瘧鍣ㄤ細鎶婁袱涓?x_constructed" 鍙橀噺鏀懼埌涓涓?bitfield 涓? 鐜板湪榪欓噷鍦ㄥ彉閲?construted"涓婂氨鏈夊涓?span style="font-weight: bold;">鏃犲唴閮ㄩ攣瀹?/span>鐨勮-鏀?瀛樻搷浣?

鐜板湪鑰冭檻涓涓嬪鏋滀竴涓嚎紼嬪皾璇曞幓鎵ц "constructed |= 1", 鑰屽湪鍚屼竴鏃墮棿鍙︿竴涓嚎紼嬪皾璇曟墽琛?"constructed |= 2".

鍦▁86騫沖彴涓? 榪欐潯璇彞浼氳姹囩紪鎴?/p>

  or constructed, 1
...
or constructed, 2
騫舵病鏈?"lock" 鍓嶇紑. 鍦ㄥ澶勭悊鏈哄櫒涓? 寰堟湁鍙兘鍙戠敓涓や釜瀛樺偍閮藉幓璇誨悓涓涓棫鍊煎茍涓斾簰鐩鎬嬌鐢ㄥ啿紿佺殑鍊艱繘琛岀鎾?clobber).

鍦?ia64 鍜?alpha騫沖彴涓? 榪欎釜紕版挒灝嗘洿鍔犳槑鏄?鍥犱負瀹冧滑涔堟病鏈夎繖鏍風殑璇?鏀?瀛?/span>鐨勫崟鏉℃寚浠? 鑰屾槸琚紪鐮佹垚涓夋潯鎸囦護:

  ldl t1,0(a0)     ; load
addl t1,1,t1     ; modify
stl t1,1,0(a0)   ; store

濡傛灉榪欎釜綰跨▼鍦?load 鍜?store涔嬮棿琚姠鍗? 榪欎釜瀛樺偍鐨勫煎彲鑳藉皢涓嶅啀鏄畠鏇劇粡瑕佸啓鍏ョ殑閭d釜鍊?

鍥犳,鐜板湪鑰冭檻涓嬮潰榪欎釜鏈夐棶棰樼殑鎵ц欏哄簭:

  • 綰跨▼A 鍦ㄦ祴璇?"constructed" 鏉′歡鍚庡彂鐜頒粬鏄浂, 騫朵笖姝h鍑嗗鎶婅繖涓艱瀹氭垚1錛?浣嗘槸瀹冭鎶㈠崰浜?
  • 綰跨▼B 榪涘叆鍚屾牱鐨勫嚱鏁? 鐪嬪埌 "constructed" 鏄浂騫剁戶緇幓鏋勯?"s" 鍜?"t", 紱誨紑鏃?"constructed" 絳変簬3.
  • 綰跨▼A 緇х畫鎵ц騫朵笖瀹屾垚瀹冪殑 璇?鏀?瀛?鐨勬寚浠ゅ簭鍒? 璁懼畾 "constructed" 鎴?1, 鐒跺悗鏋勯?"s" (絎簩嬈?.
  • 綰跨▼A 鐒跺悗緇х畫鍘繪瀯閫?"t" (絎簩嬈? 騫惰瀹?"constructed" (鏈緇? 鎴?3.

鐜板湪, 浣犲彲鑳戒細璁や負浣犺兘鐢ㄤ復鐣屽尯 (critical section) 鏉ュ皝瑁呰繖涓繍琛屾湡鍒濆鍖栧姩浣?

int ComputeSomething()
{
EnterCriticalSection(...);
static int cachedResult = ComputeSomethingSlowly();
LeaveCriticalSection(...);
return cachedResult;
}

鍥犱負浣犵幇鍦ㄦ妸榪欎釜涓嬈″垵濮嬪寲鏀懼埌浜嗕復鐣屽尯閲岄潰,鑰屼嬌瀹冪嚎紼嬪畨鍏?

浣嗘槸濡傛灉浠庡悓涓涓嚎紼嬪啀涓嬈¤皟鐢ㄨ繖涓嚱鏁頒細鎬庢牱? ("鎴戜滑璺熻釜浜嗚繖涓皟鐢? 瀹冪‘瀹炴槸鏉ヨ嚜榪欎釜綰跨▼!") 濡傛灉 ComputeSomethingSlowly() 瀹冭嚜宸遍棿鎺ュ湴璋冪敤 ComputeSomething()灝變細鍙戠敓榪欎釜鐘跺喌.

緇撹: 褰撲綘鐪嬭涓涓眬閮ㄩ潤鎬佸彉閲忓湪榪愯鏈熷垵濮嬪寲鏃? 浣犱竴瀹氳灝忓績.