Freigeben über


Avoidance of Heap Contention

Die standardmäßige Zeichenfolgenmanager, die von MFC und von ATL bereitgestellt werden, sind einfache Wrapper auf einen globalen Heaps. Dieser globale Heap ist vollständig threadsicher und bedeutet, dass mehrere Threads Speicher von ihm gleichzeitig zuordnen und freigeben können, ohne den Heap zu beschädigen. Um die Threadsicherheit bereitzustellen, muss der Heap Zugriff auf serialisieren. Dies wird normalerweise mit einem kritischen Abschnitt oder einer ähnlichen Sperrung erreicht. Wann immer zwei Threads versuchen, auf den Heap gleichzeitig zugreifen, ist ein Thread blockiert, bis die anderen Anforderungen des Threads beendet ist. Für viele Anwendungen tritt diese Situation selten auf und die Auswirkungen auf die Leistung der Sperrung des Heaps sind geringfügig. Für Anwendungen, die häufig zugreifen, können der Heap aus der mehrere Konflikt für die Sperre des Heaps kann der Anwendung verursachen, langsamer als auszuführen, wenn er singlethreaded war (sogar auf Computern mit Unterstützung mehrerer CPUs).

Anwendungen, die CStringT verwenden, sind für Heapkonflikt besonders anfällig, da Vorgänge auf CStringT-Objekte häufig Neuzuordnung des Zeichenfolgenpuffers erfordern.

Eine Möglichkeit, Heapkonflikt zwischen Threads zu mindern ist, jeden Thread Zeichenfolgen aus einem privaten, lokalen Heap zuordnen können. Solange die Zeichenfolgen, die mit der Belegungsfunktion eines bestimmten Threads zugeordnet werden, nur in diesem Thread verwendet werden, muss die Belegungsfunktion, nicht threadsicher ist.

Beispiel

Das folgende Beispiel veranschaulicht eine Threadprozedur, die den eigenen privaten Nicht-ThreadSAFE-Heap zur Verwendung für Zeichenfolgen in diesem Thread zuordnet:

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);
}

Kommentare

Mehrere Threads können mithilfe der gleichen Threadprozedur ausgeführt werden, aber, da jeder Thread über einen eigenen Heap hat, gibt es keinen Konflikt zwischen Threads. Darüber hinaus führt der Tatsache, dass jeder Heap nicht threadsicher ist, eine messbare Leistungszunahme, auch wenn nur eine Kopie des Threads ausgeführt wird. Dies ist das Ergebnis des Heaps nicht mit der teuren ineinandergegriffenen anhand der Zugriff zu schützen, Vorgänge, sich.

Für eine komplexere Threadprozedur kann es praktisch, einen Zeiger auf Zeichenfolgenmanager des Threads in einem Slot für lokalen Threadspeicher (TLS) zu speichern. Dadurch können andere Funktionen, die von der Threadprozedur aufgerufen werden, um auf den Zeichenfolgenmanager des Threads auf.

Siehe auch

Konzepte

Memory Management with CStringT