MFC两个线程用事件内核对象通信,sleep和waitforsingleobject函数的使用

编程环境
编程平台: Visual Studio 2013
框架:MFC
操作系统:Windows 10

第一步:建立一个MFC界面程序

  • 新建工程,选择“MFC”,设置好工程名MFCApplication1和保存路径;
    在这里插入图片描述
  • 选择“基于对话框”,下一步

在这里插入图片描述

  • 一直选择下一步,直到完成。然后VS自动给建立了一个名为“MFCApplication1”的工程。
    在这里插入图片描述

  • 在工程属性中,设置字符集为“多字节字符集”。不设置的话,某些地方会提示有错误。
    在这里插入图片描述

第二步:新建两个线程,线程A和线程B

说明:

  • 线程A创建后不启动,线程B创建后马上启动;
  • 事件内核对象创建时,状态为“未置信”;
  • 界面上添加一个按钮“开启线程A”,用于启动线程A,里面代码为:
	ResumeThread(hThreadA);
  • 线程A开启后,它的函数体中,将事件内核对象“置信”;

  • 线程B中,一直等待事件内核对象,当事件内核对象为“置信时”,弹窗“大家好,我叫线程B。谢谢线程A把我叫醒!”;

  • 关闭弹窗后,线程B会退出。

  • 在头文件MFCApplication1Dlg.h中,在类的定义中,声明线程处理函数,即线程入口

public:
	static DWORD __stdcall ThreadFuncA(LPVOID pParam);// Thread A
	static DWORD __stdcall ThreadFuncB(LPVOID pParam);// Thread B
  • 在MFCApplication1Dlg.cpp文件中,在开头部分添加线程句柄和ID的声明:
HANDLE hThreadA;A线程句柄
HANDLE hThreadB;B线程句柄

DWORD dwThreadIdA;  线程A的ID
DWORD dwThreadIdB;  线程B的ID

HANDLE g_hEvent;//事件内核对象的句柄
#define EventObjName "eventName"//事件名称
  • 在MFCApplication1Dlg.cpp文件中,找到对话框初始化函数,添加创建线程代码:
	创建线程A//
	hThreadA = CreateThread(NULL,/* 使用默认的安全属性 */
		100,					 /* 线程堆栈控件的大小 */
		ThreadFuncA,   /* 线程入口函数 */
		(void *)this,			 /* 线程入口函数的传入参数。这里传入的是我的窗口类对象“CMFCApplication1Dlg *const this” */
		CREATE_SUSPENDED,		 /* 标记,CREATE_SUSPENDED标识创建的线程在创建后暂停。如果为0,创建时马上运行 */
		&dwThreadIdA);			 /* 线程ID */
	SetThreadPriority(hThreadA, THREAD_PRIORITY_ABOVE_NORMAL);标识创建的线程具有的优先级别//


	创建线程B//
	hThreadB = CreateThread(NULL,/* 使用默认的安全属性 */
		100,					 /* 线程堆栈控件的大小 */
		ThreadFuncB,   /* 线程入口函数 */
		(void *)this,			 /* 线程入口函数的传入参数。这里传入的是我的窗口类对象“CMFCApplication1Dlg *const this” */
		0,		 /* 标记,CREATE_SUSPENDED标识创建的线程在创建后暂停。如果为0,创建时马上运行 */
		&dwThreadIdB);			 /* 线程ID */
	SetThreadPriority(hThreadB, THREAD_PRIORITY_ABOVE_NORMAL);标识创建的线程具有的优先级别//
	

	创建一个手动重置(manual-reset events),未受信的(nonsignaled)事件//
	g_hEvent = ::CreateEvent(NULL, TRUE, FALSE, EventObjName);
	::ResetEvent(g_hEvent);//令事件为未受信的(nonsignaled)状态//
  • 同时,添加线程处理函数
DWORD CMFCApplication1Dlg::ThreadFuncA(LPVOID pParam)
{
	g_hEvent = OpenEvent(EVENT_ALL_ACCESS, NULL, EventObjName);
	// 令事件为“置信”
	::SetEvent(g_hEvent);
	return EXIT_SUCCESS;
}
DWORD CMFCApplication1Dlg::ThreadFuncB(LPVOID pParam)
{
	g_hEvent = OpenEvent(EVENT_ALL_ACCESS, NULL, EventObjName);
	// 等待事件被“置信”,一直等待。下面这个等待语句前,一定要慎用Sleep函数。
	// Sleep(10);// 不用Sleep函数来等待了,下面函数就有等待功能。
	WaitForSingleObject(g_hEvent, INFINITE);
	AfxMessageBox("大家好,我叫线程B。谢谢线程A把我叫醒!");
	return EXIT_SUCCESS;
}
  • 退出程序时,释放事件内核对象占用的空间
    在MFCApplication1.cpp文件中,将事件内核对象的句柄声明为外部定义了的变量,用extern关键字
extern HANDLE g_hEvent;//事件内核对象的句柄

然后,在程序实例退出的地方,添加关闭句柄的语句:

	else if (nResponse == IDCANCEL)
	{
		// TODO:  在此放置处理何时用
		//  “取消”来关闭对话框的代码
		CloseHandle(g_hEvent);
	}
  • 运行效果:
    在这里插入图片描述
    在这里插入图片描述
    有疑问可以留言哦。

放上代码链接:
MFC两个线程中用事件内核对象通信
https://download.csdn.net/download/u012210613/11046606

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值