我在谷歌搜索中获得了以下代码,因为我正在尝试学习多线程。我使用CRITICAL SECTION运行代码而没有CRITICAL SECTION,但在执行了这两种情况之后,我不明白为什么这段代码的作者使用了CRITICAL SECTION。
static unsigned int counter = 100;
static bool alive = true;
CRITICAL_SECTION cs;
static unsigned __stdcall Sub(void *args)
{
while(alive)
{
EnterCriticalSection(&cs);
cout << "[Sub(" << counter << ")]---" << endl;
counter -= 10;
LeaveCriticalSection(&cs);
Sleep(500);
}
return 0;
}
static unsigned __stdcall Add(void *args)
{
while(alive)
{
EnterCriticalSection(&cs);
cout << "[Add(" << counter << ")]+++" << endl;
counter += 10;
LeaveCriticalSection(&cs);
Sleep(500);
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
InitializeCriticalSection(&cs);
unsigned add;
HANDLE hAdd = (HANDLE)_beginthreadex(0,0,&Add,0,CREATE_SUSPENDED, &add);
assert(hAdd != 0);
unsigned sub;
HANDLE hSub = (HANDLE)_beginthreadex(0,0,&Sub,0,CREATE_SUSPENDED, &sub);
assert(hSub != 0);
//start threads
ResumeThread(hAdd);
ResumeThread(hSub);
//let threads run for 10 seconds
Sleep(3000);
alive = false;
WaitForSingleObject(hSub, INFINITE);
CloseHandle(hSub);
WaitForSingleObject(hAdd, INFINITE);
CloseHandle(hAdd);
return 0;
}
答案 0 :(得分:2)
你有两个并行运行的线程,读取(cout << "[Sub(" << counter << ")]---" << endl
)和读/写(counter -= 10)
一个共享变量。如果在读取和写入之间,你会怎么想?其他线程写入值?如果您尝试根据counter
的值做出决策,当同一个变量的两个不同读取可能返回不同的值时会怎样?
以下序列可能(可能会也可能不会):
thread SUB: read counter [say, 100]
thread ADD: read counter [100]
thread ADD: write counter <- 110
thread SUB: write counter <- 90
使用CRITICAL_SECTION,你有:
thread SUB: read counter [say, 100]
thread SUB: write counter <- 90
thread ADD: read counter [90]
thread ADD: write counter <- 100
或者你有:
thread ADD: read counter [100]
thread ADD: write counter <- 110
thread SUB: read counter [110]
thread SUB: write counter <- 100
无论哪种方式,使用CRITICAL_SECTION,最终结果为100,没有你可能最终得到90.
CRITICAL_SECTION允许将代码块作为“工作单元”执行,而不会受到同一CRITICAL_SECTION上的另一个线程阻塞的干扰。
答案 1 :(得分:1)
CRITICAL_SECTION是一种用于多线程的简单同步机制。 您使用CRITICAL_SECTION来保护代码块不会同时运行两个或多个线程。
在大多数情况下,无论是否存在受保护的共享资源,都不会有任何区别,例如:
想象一下,两个线程同时访问资源,如内存块,一个读取图像,另一个读取图像。阅读线程将获得损坏的图像。
我建议你多做一些关于多线程的阅读,以便更好地理解概念以及如何使用同步对象来控制多线程应用程序中的流程。