Поделиться через


Avoidance of Heap Contention

По умолчанию диспетчер строки, предоставляемые MFC и библиотеки ATL простые программы-оболочки поверх глобальной куче. Эта глобальной куче полностью потокобезопасной, означать, что несколько потоков могут выбирать и освобождать память из нее одновременно, не повредить кучу. Чтобы обеспечить потокобезопасность, куча должна выполнить сериализацию к самому себе. Обычно это выполняется с критической секцией или аналогично блокируя механизмом. При попытке доступа к куче 2 потока одновременно, один поток блокироваться до тех пор, пока запрос другого потока. Для многих приложений эта ситуация возникает редко, и влияние на производительность механизма кучи блокируя на производительность незначительно. Однако для приложений, которые часто обращаются к куче из конфликтов нескольких потоков для блокировки кучи может привести к приложению выполняться медленнее, чем если она была продета потоками (даже на компьютерах с несколькими ЦП).

Приложения, использующие CStringT особенно впечатлительный для навалить конфликт, так как операции в объектах CStringT часто необходима перераспределения буфера строки.

Один из способов решить конфликты кучи между потоками иметь каждый поток выборки строк из строки поток- локальной куче. Если строки, выбранные с помощью механизма распределения указанного потока используются только в этом потоке, выделения не должны быть потокобезопасным.

Пример

В приведенном ниже примере демонстрируются процедуры потока, которая выделяет собственную non-поток- защищенной частной кучи для использования строк в этом потоке.

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). Это позволяет другие функции, вызываемые процедурой потока для доступа к диспетчеру строки потока.

См. также

Основные понятия

Memory Management with CStringT