首页 > 代码库 > 多线程简易售票程序--孙鑫视频示例

多线程简易售票程序--孙鑫视频示例

孙鑫视频多线程的第一个例子----简易的售票程序

#include <Windows.h>
#include <iostream>

int ticket = 100;
//定义互斥对象
/*
互斥对象属于内核对象,它能够准确保证线程拥有对单个资源的互斥访问
互斥对象包含一个使用数量 线程ID  计数器
ID用于标识系统中哪个线程当前拥有互斥对象,计数器用于指明该线程拥有互斥对象的次数
*/
HANDLE hMutex;
DWORD WINAPI FunProc_1(LPVOID lpParameter)
{
	while(true)
	{
		//设置hMutex为未通知状态
		//请求互斥对象
		WaitForSingleObject(hMutex , INFINITE);
		if(ticket > 0)
		{
			Sleep(1);
			std::cout << "hThread1 ticket sell :" << ticket-- << std::endl;
		}else{
			break;
		}
		//释放互斥对象,将互斥对象设置为通知对象
		ReleaseMutex(hMutex);
	}
	return 0;
}
DWORD WINAPI FunProc_2(LPVOID lpParameter)
{
	while(true)
	{
		//设置hMutex为未通知状态
		//请求互斥对象
		WaitForSingleObject(hMutex , INFINITE);
		if(ticket > 0)
		{
			Sleep(1);
			std::cout << "hThread2 ticket sell :" << ticket-- << std::endl;
		}else{
			break;
		}
		//释放互斥对象,将互斥对象设置为通知对象
		//当释放的时候,系统会判断当前线程ID和互斥对象hMutex内部的ID,相等才能释放,不等则不能释放
		//谁拥有互斥对象,谁才能去释放互斥对象,这样才能成功释放
		//ReleaseMutex实际上递减互斥对象的计数器
		ReleaseMutex(hMutex);
	}
	return 0;
}
int main()
{
	HANDLE hThread1 , hThread2;
	//创建线程
	hThread1 = CreateThread(NULL , 0 , FunProc_1 , NULL , 0 , NULL);
	hThread2 = CreateThread(NULL , 0 , FunProc_2 , NULL , 0 , NULL);
	//关闭句柄并不是终止新创建线程,在主线程中关闭新创建线程的引用
	//内核对象引用计数器减1,当内核对象的引用计数器为0时释放内核对象
	//类似于c++中的句柄类中的引用计数
	CloseHandle(hThread1);
	CloseHandle(hThread2);
	//创建/打开互斥对象
	//TRUE调用该互斥对象获得所有权,反之是不获得
	//当为FALSE时也就是主线程不获得hMutex的使用权
	//当为TRUE时,主线程拥有了互斥对象,而主线程并没有释放,其他两个线程便得不到互斥对象的所有权
	hMutex = CreateMutex(NULL , FALSE , NULL);
	Sleep(1000);
	return 0;
}