Win32学习(第十二天)线程通讯

线程通讯:
线程需要在两种情况下进行通讯
1、如果有多个线程访问共享资源而不能够使这个资源被破坏
2、当一个线程将某一个任务完成之后,通知另一个线程接着去完成下一个任务

线程的互斥访问分为
1、用户区间
2、内核对象(但内核对象并不是只能用来做线程互斥)
这里采用一个控制台应用程序进行说明:

//一、用户区间
//临界区

//临界区  1、定义一个临界区变量
//CRITICAL_SECTION g_cs;

//二、内核对象
//内核对象都可以处于已通知和未通知的两种状态,状态的切换是系统的规则来决定的
//在线程的运行过程中,线程内核对象处于未通知状态,当线程结束时,变为已通知(抢占)

//事件   基于内核对象的同步机制
//事件  1、事件的句柄的定义
//HANDLE g_hEvent;

//互斥对象  用来确保线程的单个资源的互斥访问权
//包含一个使用数量,一个线程id和一个递归的计数器
//而互斥对象的行为和临界区有些类似,只不过互斥属于内核,临界区属于用户
//id来标识系统中哪个线程拥有互斥对象,递归计数器用于表示这个线程拥有互斥对象的次数
//互斥对象的使用规则:如果线程id为0,表示无效id,没有线程拥有互斥对象,互斥对象发出信号
//如果id非0,证明有线程拥有互斥对象,不发出信号。

//互斥对象  1、互斥对象句柄的定义
//HANDLE g_hMutex;

//信号量  1、信号量对象句柄的定义
HANDLE g_hSemaphore;

int piao = 10;
void aa(LPVOID v)
{
	

	while (1)
	{//临界区  3、进入临界区
		//EnterCriticalSection(&g_cs);

		//事件  3、等待通知
		//WaitForSingleObject(g_hEvent, INFINITE);
     
		//互斥   3、等待通知
		//WaitForSingleObject(g_hMutex, INFINITE);
	
		//信号量  3、等待通知
		WaitForSingleObject(g_hSemaphore, INFINITE);
		if (piao > 0)
		{
			printf("第%d个车站抢到第%d张票\n", (int)v, piao);
			piao--;
		}
		else{
			//临界区  4、离开临界区
			//LeaveCriticalSection(&g_cs);

			//事件  4、设置事件通知
			//SetEvent(g_hEvent);

			//互斥 4、重置互斥内核
			//ReleaseMutex(g_hMutex);

			//信号量  4、重置信号量
			//第二个参数重置当前的资源数量
			ReleaseSemaphore(g_hSemaphore, 1, 0);
			break;
		}
		//LeaveCriticalSection(&g_cs);
		//SetEvent(g_hEvent);
		//ReleaseMutex(g_hMutex);
		ReleaseSemaphore(g_hSemaphore, 1, 0);
	}
}

int _tmain(int argc, _TCHAR* argv[])

{
	//临界区  2、临界区变量初始化
	//InitializeCriticalSection(&g_cs);

	//事件   2、事件的初始化
	//第2个参数表示重置,自动事件(重置),手动事件(重置)false(人工重置)
	//自动重置:表示事件得到通知,等待这个事件的线程只有一个线程变为可调度线程
	//手动重置:表示事件已经得到通知,等待这个事件的所有线程都变为可调度线程
	//g_hEvent = CreateEvent(nullptr,//安全属性
		//false,//自动事件还是手动事件
		//true,//事件的初始值(已通知)
		//nullptr);//事件内核对象名称

    //互斥  2、互斥的初始化
	//第二个参数:如果为false,表示互斥对象拥有的id和计数器为0
	        //如果为true,表示互斥对象拥有的id为调用线程id,计数器++;
	//g_hMutex = CreateMutex(nullptr, false, nullptr);


	//信号量  2、信号量的初始化
	//第2/3个参数是借助信号量的特点,给出1,初始化的数量为1,最大数也为1,如果线程占用了,初始数量为1
	g_hSemaphore = CreateSemaphore(nullptr, 1, 1, nullptr);
	int index = 1;
	HANDLE handle1 = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)aa, (LPVOID)index, 0, 0);
	index++;
	HANDLE handle2 = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)aa, (LPVOID)index, 0, 0);
	index++;
	HANDLE handle3 = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)aa, (LPVOID)index, 0, 0);
	index++;
	HANDLE handle4 = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)aa, (LPVOID)index, 0, 0);
	while (1)
	{
		//临界区  3、进入临界区
		//EnterCriticalSection(&g_cs);

		//内核和用户区间是有区别的,内核会自动切换状态不需要手动去设置
		//事件   3、等待通知
		//WaitForSingleObject(g_hEvent, INFINITE);

		//互斥  3、等待通知
		//WaitForSingleObject(g_hMutex, INFINITE);

		//信号量  3、等待通知
		WaitForSingleObject(g_hSemaphore, INFINITE);

		if (piao > 0)
		{
			printf("火车站抢到第%d张票\n", piao);
			piao--;
		}
		else
		{
			//临界区 4、离开临界区
			//LeaveCriticalSection(&g_cs);

			//事件  4、设置事件通知
			//SetEvent(g_hEvent);

			//互斥  4、重置互斥内核
			//ReleaseMutex(g_hMutex);

			//信号量  4、重置信号量
			//第2个参数表示重置当前的资源的数量
			ReleaseSemaphore(g_hSemaphore, 1, 0);
			break;
		}
		//LeaveCriticalSection(&g_cs);

		//事件  设置事件的通知
		//SetEvent(g_hEvent);

		//互斥  4、重置互斥内核
		//ReleaseMutex(g_hMutex);

		//信号量  4、重置信号量
		//第2个参数表示重置当前资源的数量
		ReleaseSemaphore(g_hSemaphore, 1, 0);
	}
	//临界区  5、释放临界区
	//DeleteCriticalSection(&g_cs);

	//事件  关闭事件
	//CloseHandle(g_hEvent);

	//互斥  5、关闭互斥
	//CloseHandle(g_hMutex);

	//信号量  5、关闭信号量
	CloseHandle(g_hSemaphore);

	DWORD t1, t2, t3, t4;
	while (1)
	{
		GetExitCodeThread(handle1, &t1);//得到线程的退出码
		GetExitCodeThread(handle2, &t2);
		GetExitCodeThread(handle3, &t3);
		GetExitCodeThread(handle4, &t4);

		//判断线程退出码如果是STILL_ACTIVE,表示线程仍然活跃,非STILL_ACTIVE,表示线程死亡
		if (t1 != STILL_ACTIVE&&t2 != STILL_ACTIVE&&t3 != STILL_ACTIVE&&t4 != STILL_ACTIVE)
		{
			break;
		}
	}
	TerminateThread(handle1, 0);//终止进程
	TerminateThread(handle2, 0);
	TerminateThread(handle3, 0);
	TerminateThread(handle4, 0);
	getchar();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值