我是靠谱客的博主 笑点低柠檬,最近开发中收集的这篇文章主要介绍vc c语言多线程,VC 线程间通信的三种方式,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

// 线程通信用全局变量

volatile bool g_bDo = false;

……

//线程处理函数

UINT ThreadProc5(LPVOID pParam)

{

//根据全局变量g_bDo的取值来决定线程的运行

while (g_bDo)

{

Sleep(2000);

AfxMessageBox("线程正在运行!");

}

AfxMessageBox("线程终止");

return 0;

}

……

void CSample06View::OnGlobalStart()

{

// 通过全局变量通知线程执行

g_bDo = true;

// 启动线程

AfxBeginThread(ThreadProc5, NULL);

}

void CSample06View::OnGlobalEnd()

{

// 通过全局变量通知线程结束

g_bDo = false;

}

2.利用自定义消息(可适用于窗体)

全局变量在线程通信中的应用多用在主线程对子线程的控制上,而从子线程向主线程的信息反馈则多采用自定义消息的方式来进行。这里对自定义消息的使用同使用普通自定义消息非常相似,只不过消息的发送是在子线程函数中进行的。该方法的主体是自定义消息,应首先定义自定义消息并添加对消息的响应代码。

// 自定义消息

#define WM_USER_MSG WM_USER + 101

……

//消息响应函数在头文件中的定义:

//{{AFX_MSG(CSample06View)

//}}AFX_MSG

afx_msg void OnUserMsg(WPARAM wParam, LPARAM lParam);

DECLARE_MESSAGE_MAP()

……

//消息映射

BEGIN_MESSAGE_MAP(CSample06View, CView)

//{{AFX_MSG_MAP(CSample06View)

//}}AFX_MSG_MAP

ON_MESSAGE(WM_USER_MSG, OnUserMsg)

END_MESSAGE_MAP()

……

//消息响应函数

void CSample06View::OnUserMsg(WPARAM wParam, LPARAM lParam)

{

// 报告消息

AfxMessageBox("线程已退出!");

}

此后,在子线程函数需要向主线程发送消息的地方调用PostMessage()或SendMessage()消息传递函数将消息发送给主线程即可。由于消息发送函数是在线程中被调用,因此需要指出接受窗口句柄,可通过线程参数将其传递进线程函数。

UINT ThreadProc6(LPVOID pParam)

{

// 延迟一秒

Sleep(1000);

// 向主线程发送自定义消息

::PostMessage((HWND)pParam, WM_USER_MSG, 0, 0);

return 0;

}

……

void CSample06View::OnUseMessage()

{

// 获取窗口句柄

HWND hWnd = GetSafeHwnd();

// 启动线程

AfxBeginThread(ThreadProc6, hWnd);

}

3.使用事件内核对象(相当好用)

利用事件(Event)内核对象对线程的通信要复杂些,主要通过对事件对象的监视来实现线程间的通信。事件对象由CreateEvent()函数来创建,具有两种存在状态:置位与复位,分别由SetEvent()和ResetEvent()来产生。事件的置位将通过 WaitForSingleObject()或WaitForMultipleObjects()之类的通知等待函数继续执行。

// 事件句柄

HANDLE hEvent = NULL;

UINT ThreadProc7(LPVOID pParam)

{

while(true)

{

// 等待事件发生

DWORD dwRet = WaitForSingleObject(hEvent, 0);

// 如果事件置位则退出线程,否则将继续执行

if (dwRet == WAIT_OBJECT_0)

break;

else

{

Sleep(2000);

AfxMessageBox("线程正在运行!");

}

}

AfxMessageBox("线程终止运行!");

return 0;

}

……

void CSample06View::OnEventStart()

{

// 创建事件

hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

// 启动线程

AfxBeginThread(ThreadProc7, NULL);

}

void CSample06View::OnEventEnd()

{

// 事件置位

SetEvent(hEvent);

}

上面这段代码展示了事件对象在线程通信中的作用。在创建线程前首先创建一个事件对象hEvent,这里CreateEvent()函数所采用的四个参数分别表示句柄不能被继承、事件在置位后将由系统自动进行复位、事件对象初始状态为复位状态和不指定事件名。在创建的子线程中使用 WaitForSingleObject()对hEvent进行监视。WaitForSingleObject()的函数原型为:

DWORD WaitForSingleObject(

HANDLE hHandle,                             //等待对象的句柄

DWORD dwMilliseconds           //超过时间间隔

);

函数将在hHandle对象有信号时或是在等待时间超出由dwMilliseconds设定的超时时间间隔返回。其返回值可以为 WAIT_ABANDONED、WAIT_OBJECT_0和WAIT_TIMEOUT,分别表示被等待的互斥量(Mutex)对象没有被释放、等待的对象信号置位和超时。通过对返回值的判断可以区分出引起WaitForSingleObject()函数返回的原因。在本例中只关心 WAIT_OBJECT_0的返回值,当通过SetEvent()将hEvent置位后即可使WaitForSingleObject()立即返回并通过跳出循环而结束线程。

最后

以上就是笑点低柠檬为你收集整理的vc c语言多线程,VC 线程间通信的三种方式的全部内容,希望文章能够帮你解决vc c语言多线程,VC 线程间通信的三种方式所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(56)

评论列表共有 0 条评论

立即
投稿
返回
顶部