Win32系统编程 临界区

临界区是什么?

要回答这个问题还得先了解一个线程安全问题,每个线程都有自己的栈,而局部变量是存储在栈中的,这就意味着每个线程都有一份自己的"局部变量",如果线程仅仅使用局部变量,那就不存在线程安全问题了,那如果是多个线程共用一个全局变量呢?

下面我们写个简单的案例(他们总喜欢用卖票的例子,这里我就偏偏要用卖花的):

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
int testnum = 10;
DWORD WINAPI ThreadPoc(LPVOID  lpParameter)
{
	
	while (testnum>0)
	{
		printf("还有:%d朵花\n", testnum);
		testnum--;
		printf("卖出一朵,还有:%d朵\n", testnum);
	}

	return 0;

}

int main()
{

	HANDLE testThread[2];

	testThread[0] = CreateThread(NULL, NULL, ThreadPoc, NULL, 0, NULL);
	testThread[1] = CreateThread(NULL, NULL, ThreadPoc, NULL, 0, NULL);

	CloseHandle(testThread);
	system("pause");

}

下面是程序出现的诡异现象:

出现了还有10朵花卖出去一朵还剩下8朵的诡异情况,这种情况就是两个线程同时访问一个全局变量引发的安全问题,因为两个线程来回不停的切换,可能卖花人A去看总数的时候还剩下10朵,但是下一瞬间卖花人B就卖出去一朵,这个时候全局变量减1,而卖花人A还以为剩下的总数是十朵,从而引发的安全问题。
在这里插入图片描述

临界区

那么为了解决这个安全问题,引申出我们的主题临界区,那为了解决这个安全问题,如果可以管理多个线程同时使用同一个全局变量的时候,每一次只能有一个线程可以访问到这个全局变量,那么这个全局变量被称为临界资源,而这些被管理的线程被称之为临界区。

实现方式图例:

实现方式,当多个线程同事访问全局变量X的时候,需要先拿到令牌,比如线程1先访问到X,则拿到令牌0,其它2 3再想去访问的时候,就发现令牌变为1了,则只能等待线程1把令牌0归还后再访问全局变量X。
在这里插入图片描述

临界区的代码实现

临界区实现之线程锁:
(1)创建全局变量
CRITICAL_SECTION cs;
(2)初始化全局变量
lnitializeCriticalSection(&cs)
(3)实现临界区
EnterCriticalSection(&cs);
//使用临界区资源
LeaveCriticalSection(&cs);
//退出临界区资源

代码使用演示:

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
int testnum = 10;
CRITICAL_SECTION cs;



DWORD WINAPI ThreadPoc(LPVOID  lpParameter)
{
	
	EnterCriticalSection(&cs);
	while (testnum>0)
	{
		printf("还有:%d朵花\n", testnum);
		testnum--;
		printf("卖出一朵,还有:%d朵\n", testnum);
	}
	LeaveCriticalSection(&cs);

	return 0;

}

int main()
{
	InitializeCriticalSection(&cs);
	HANDLE testThread[2];

	testThread[0] = CreateThread(NULL, NULL, ThreadPoc, NULL, 0, NULL);
	testThread[1] = CreateThread(NULL, NULL, ThreadPoc, NULL, 0, NULL);

	CloseHandle(testThread);
	system("pause");

}

代码运行结果:

诡异现象不再出现
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值