2021-03-15Win3200
请注意,本文编写于 624 天前,最后修改于 204 天前,其中某些信息可能已经过时。

目录


1. 线程安全问题

每个线程都有自己的栈,而局部变量是存储在栈中的,这就意味着每个线程都有一份自己的“局部变量”,如果线程仅仅使用“局部变量”那么就不存在线程安全问题。

那如果多个线程共用一个全局变量呢?,当多个线程对同一个全局变量做读取,写入的操作时就有可能出现安全问题

可能会出现卖出同一张票以及超卖的问题

安全问题

2. 解决思路

给全局变量起个名字,叫临界资源
临界资源: 一次只允许一个线程使用的资源

解决思路

首先获取令牌,看令牌有没有人在使用,如果没人使用就拿到这个令牌,同时将令牌置为占用,然后对全局变量进行访问,

此时如果有其他线程要访问这个全局变量,那依然需要先查看令牌又没有人使用,如果令牌是占用的状态,那么此时无法对全局变量进行访问

3. 临界区实现之线程锁

<1> 创建全局变量
CRITICAL_SECTION cs;

<2> 初始化全局变量
InitializeCriticalSection(&cs);

<3> 实现临界区

EnterCriticalSection(&cs);
	//使用临界资源
LeaveCriticalSection(&cs);
c
/*===============================================================

临界区:
修改的代码,使其安全

===============================================================*/
# include "windows.h"
# include "stdio.h"

//全局资源
int iTicket = 10;

//临界区
CRITICAL_SECTION cs;

DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
	while (1)
	{
	    //进入临界区
		EnterCriticalSection(&cs);
		if (iTicket > 0)
		{
			printf("开始买票....\n");
			iTicket--;
			printf("买票成功,  还剩 %d 张票!\n", iTicket);
		}
		else
		{
			printf("票已卖完**********\n");
			//离开临界区
			LeaveCriticalSection(&cs);
			break;
		}
		//离开临界区
		LeaveCriticalSection(&cs);
	}
}


int main()
{
	HANDLE hThread[2] = { 0 };

	//初始化临界区
	InitializeCriticalSection(&cs);

	hThread[0] = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
	hThread[1] = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);

	WaitForMultipleObjects(2, hThread, TRUE, -1);

	printf("两个线程运行完毕!\n");

	CloseHandle(hThread[0]);
	CloseHandle(hThread[1]);

	getchar();
	return 0;
}

本文作者:Na1r

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!