windows API(9)线程安全 临界区
程序员文章站
2022-03-05 09:55:23
...
线程安全问题
每一个线程都有自己的栈区,而局部变量是存储在栈中的,这就意味着每个线程都有一份自己的局部变量,如果线程仅仅使用“局部变量”则不存在线程安全问题。
但是,如果使用全局变量就会存在线程安全问题。
解决方法-临界区
我们将全局变量称为临界资源,就是一次只允许一个线程进行使用。
访问临界资源的代码就称为临界区。
原理:我们对临界资源增加令牌,只有当令牌为1时代码才可以对临界区进行访问,同时将令牌置0。其它线程便无法访问该临界资源
临界区实现之线程锁:
- 创建全局变量 CRITICAL_SECTION cs
- 初始化全局变量 InitializeCriticalSection(&cs)
- 实现临界区
EnterCriticalSection(&cs);
//使用临界资源
LeaveCriticalSection(&cs);
注意:所有关于逻辑判断的代码都要放在临界区之内
实例
int dwTickets = 10;
//给全局变量加锁
CRITICAL_SECTION cs;
DWORD WINAPI ThreadProc(LPVOID lpParament)
{
//创建临界区
EnterCriticalSection(&cs);
//判断是否还有票
while (dwTickets > 0)
{
printf("还有多少张票%d\n", dwTickets);
--dwTickets;
printf("还剩多少张票%d\n", dwTickets);
}
LeaveCriticalSection(&cs);
return 0;
}
int main(int argc, char* argv[])
{
HANDLE harrThread[2];
DWORD dwResult1;
DWORD dwResult2;
//初始化全局变量
InitializeCriticalSection(&cs);
harrThread[0] = CreateThread(NULL, 0, ThreadProc, NULL, NULL, NULL);
harrThread[1] = CreateThread(NULL, 0, ThreadProc, NULL, NULL, NULL);
//在线程全部执行完毕后,才会接着执行下面的内容
WaitForMultipleObjects(2, harrThread, TRUE, INFINITE);
printf("线程执行完毕\n");
CloseHandle(harrThread[0]);
CloseHandle(harrThread[1]);
return 0;
}
上一篇: redis-阻塞
下一篇: 安装elasticsearch