共用方式為


避免堆積競爭

MFC 和 ATL 所提供的預設字串管理員是全域堆積頂端的簡單包裝函式。 這個全域堆積完全安全線程,這表示多個執行緒可以同時配置和釋放記憶體,而不會損毀堆積。 為了協助提供執行緒安全性,堆積必須序列化本身的存取權。 這通常是使用重要區段或類似的鎖定機制來完成。 每當兩個執行緒嘗試同時存取堆積時,就會封鎖一個執行緒,直到另一個執行緒的要求完成為止。 對於許多應用程式而言,這種情況很少發生,而且堆積鎖定機制的效能影響微不足道。 不過,對於經常從堆積鎖定的多個執行緒爭用存取堆積的應用程式,可能會導致應用程式執行速度比單一執行緒更慢(即使是在具有多個 CPU 的電腦上)。

使用 CStringT 的應用程式特別容易發生堆積爭用,因為物件上的 CStringT 作業通常需要重新配置字串緩衝區。

緩和執行緒之間堆積爭用的其中一種方法是讓每個執行緒從私人執行緒本機堆積配置字串。 只要配置給特定執行緒的配置器所配置的字串只會在該執行緒中使用,配置器就不需要安全線程。

範例

下列範例說明執行緒程式,其會配置自己的私人非執行緒安全堆積,以用於該執行緒上的字串:

DWORD WINAPI WorkerThreadProc(void* pBase)
{
   // Declare a non-thread-safe heap just for this thread:
   CWin32Heap stringHeap(HEAP_NO_SERIALIZE, 0, 0);

   // Declare a string manager that uses the thread's heap:
   CAtlStringMgr stringMgr(&stringHeap);

   int nBase = *((int*)pBase);
   int n = 1;
   for(int nPower = 0; nPower < 10; nPower++)
   {
      // Use the thread's string manager, instead of the default:
      CString strPower(&stringMgr);

      strPower.Format(_T("%d"), n);
      _tprintf_s(_T("%s\n"), strPower);
      n *= nBase;
   }

   return(0);
}

註解

多個執行緒可以使用這個相同的執行緒程式來執行,但因為每個執行緒都有自己的堆積,執行緒之間沒有爭用。 此外,即使只執行執行緒的一份複本,每個堆積都不是安全線程,也能大幅提升效能。 這是堆積未使用昂貴的聯結作業來保護平行存取的結果。

對於更複雜的執行緒程式,將執行緒字串管理員的指標儲存線上程本機儲存體 (TLS) 位置可能很方便。 這可讓執行緒程式呼叫的其他函式存取執行緒的字串管理員。

另請參閱

使用 CStringT 管理記憶體