线程同步之关键段
[什么是关键段]
关键段(Critical section)是一小段代码,它在执行之前需要独占一些共享资源的访问权。这种方式可以上多行代码以"原子方式"来对资源进行操控。这里的原子方式,是指代码知道除了当前线程以外,没有其他任何线程会同时访问该资源。
[什么时候使用]
当我们有一个资源要让多个线程访问时;
当不能用Interlocked函数解决同步问题时;
[怎么使用关键段]
#include <Windows.h> DWORD WINAPI FirstThread(PVOID pvParam); DWORD WINAPI SecondThread(PVOID pvParam); #define COUNTNUMBER 10 int g_Number = 0; CRITICAL_SECTION g_cs; int WINAPI WinMain( IN HINSTANCE hInstance, IN HINSTANCE hPrevInstance, IN LPSTR lpCmdLine, IN int nShowCmd ) { char cThreadBuffer[260] = {NULL}; HANDLE hFirstThread = CreateThread(NULL, 0, FirstThread, NULL, 0, NULL); HANDLE hSecondThread = CreateThread(NULL, 0, SecondThread, NULL, 0, NULL); wsprintf(cThreadBuffer, "%d", g_Number); MessageBox(0, cThreadBuffer, "Tips", MB_OK); return 0; } DWORD WINAPI FirstThread(PVOID pvParam) { // //使用前必须初使化 // InitializeCriticalSection(&g_cs); EnterCriticalSection(&g_cs); g_Number = 0; for (int n=0; n< COUNTNUMBER; n++) { g_Number += n; } char cFirstThreadBuffer[260] = {NULL}; wsprintf(cFirstThreadBuffer, "First:%d", g_Number); MessageBox(0, cFirstThreadBuffer, "Tips", MB_OK); LeaveCriticalSection(&g_cs); return (g_Number); } DWORD WINAPI SecondThread(PVOID pvParam) { // //使用前必须初使化 // InitializeCriticalSection(&g_cs); EnterCriticalSection(&g_cs); g_Number = 0; for (int n= 0;n< COUNTNUMBER; n++) { g_Number += n; } char cSecondThreadBuffer[260] = {NULL}; wsprintf(cSecondThreadBuffer, "Second:%d", g_Number); MessageBox(0, cSecondThreadBuffer, "Tips", MB_OK); LeaveCriticalSection(&g_cs); return (g_Number); }
首先定义了一个g_cs的CRITICAL_SECTION结构,把任何需要修改共享资源(g_Number)的代码放到EnterCriticalSection和LeaveCriticalSection之间。
如果忘了任何线程哪怕一个地方没有加EnterCriticalSection和LeaveCriticalSection,共享资源都有被破坏的可能。
[缺点]
最大缺点是在于它们无法用来在多个进程之间对线程进行同步
2012-10-25

浙公网安备 33010602011771号