Aracılığıyla paylaş


Yığın Çekişmesini Engelleme

MFC ve ATL tarafından sağlanan varsayılan dize yöneticileri, genel yığın üzerinde basit sarmalayıcılardır. Bu genel yığın tamamen iş parçacığı açısından güvenlidir, başka bir deyişle birden çok iş parçacığı yığını bozmadan aynı anda ondan bellek ayırabilir ve boşaltabilir. İş parçacığı güvenliği sağlamaya yardımcı olmak için yığının kendisine erişimi seri hale getirmesi gerekir. Bu genellikle kritik bir bölüm veya benzer bir kilitleme mekanizmasıyla gerçekleştirilir. İki iş parçacığı yığına aynı anda erişmeye çalıştığında, diğer iş parçacığının isteği tamamlanana kadar bir iş parçacığı engellenir. Birçok uygulama için bu durum nadiren ortaya çıkar ve yığının kilitleme mekanizmasının performans etkisi göz ardı edilebilir. Bununla birlikte, yığının kilidi için birden çok iş parçacığı çekişmesi nedeniyle yığına sık erişen uygulamalar, uygulamanın tek iş parçacıklı (birden çok CPU'su olan makinelerde bile) daha yavaş çalışmasına neden olabilir.

Nesnelerdeki CStringT işlemler genellikle dize arabelleğinin yeniden yerleştirilmesini gerektirdiğinden, CStringT kullanan uygulamalar özellikle yığın çekişmelerine duyarlıdır.

İş parçacıkları arasındaki yığın çekişmelerini azaltmanın bir yolu, her iş parçacığının özel, iş parçacığı yerel yığınından dize ayırmasını sağlamaktır. Belirli bir iş parçacığının ayırıcısıyla ayrılan dizeler yalnızca bu iş parçacığında kullanıldığı sürece ayırıcının iş parçacığı güvenli olması gerekmez.

Örnek

Aşağıdaki örnekte, bu iş parçacığındaki dizeler için kullanmak üzere kendi özel iş parçacığı güvenli olmayan yığınını ayıran bir iş parçacığı yordamı gösterilmektedir:

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

Açıklamalar

Aynı iş parçacığı yordamı kullanılarak birden çok iş parçacığı çalışıyor olabilir, ancak her iş parçacığının kendi yığını olduğundan, iş parçacıkları arasında çekişme yoktur. Ayrıca, her yığının iş parçacığı güvenli olmaması, iş parçacığının yalnızca bir kopyası çalışıyor olsa bile performansta ölçülebilir bir artış sağlar. Bu, yığının eşzamanlı erişime karşı korumak için pahalı birbirine bağlı işlemleri kullanmaması sonucudur.

Daha karmaşık bir iş parçacığı yordamı için, iş parçacığının dize yöneticisine yönelik bir işaretçiyi bir iş parçacığı yerel depolama (TLS) yuvasında depolamak kullanışlı olabilir. Bu, iş parçacığı yordamı tarafından çağrılan diğer işlevlerin iş parçacığının dize yöneticisine erişmesine olanak tanır.

Ayrıca bkz.

CStringT ile Bellek Yönetimi