线程间的通信实例

线程间的通信主要针对主线程和次线程来说。而线程间的同步是针对两个或多个次线程来说的。

一般而言,应用程序中的一个次要线程总是为主线程执行特定的任务,这样,主线程和次要线程间必定有一个信息传递的渠道,也就是主线程和次要线程间要进行通信。这样线程间的通信不但是难以避免的,而且在多线程编程中也是复杂和频繁的。一般可以使用全局变量进行通信和自定义消息进行通信。

1.使用全局变量进行通信

由于属于同一个进程的各个线程共享操作系统分配该进程的资源,所以可以通过全局变量来解决线程间的通信。建议使用 volatile 修饰符,它告诉编译器无需对该变量进行任何的优化,即无需将它放到一个寄存器中,并且该值可被外部改变。如果线程间所需传递的信息比较复杂,可以定义一个结构,通过传递指向该结构的指针进行传递消息。接着让线程监视这个变量(标志位),当这个变量符合一定的条件时,表示线程应该终止。

bool bExit = 1;                     //全局变量,用来监视线程是否结束,可以在需要结束
                                    //线程的地方将 bExit 置为 0
UINT WorkThread(LPVOID param)       //全局线程函数
{
    int nPos = 0;
    while(nPos < 500 && bExit)      
        nPos++;
    return 0;
}

2.使用自定义消息进行通信

博主写过的自定义消息:https://blog.csdn.net/qq_41291253/article/details/103321802

可以在一个线程的执行函数中向另一个线程发送自定义的消息来达到通信的目的。一个线程向另一个线程发送消息是通过操作系统来实现的。利用 Windows 操作系统的消息驱动机制,当一个线程发出一条消息时,操作系统首先接收到该消息,然后把该消息转发给目标线程(接收消息的线程必须已经建立了消息循环)。

使用 Windows 消息来进行通信,首先需要定义一个自定义消息,然后,需要时在一个线程中调用全局函数::PostMessage()向另一个线程发送自定义消息。PostMessage()函数原型为

BOOL PostMessage(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam);
其中,参数hwnd为要接收消息窗口的句柄,参数 Msg 为消息的 ID,参数wParam lParam为消息相关的参数。

例:编写一个创建工作者线程的单文档应用程序,当执行“延时”菜单命令时启动一个工作者线程,延时 3 秒后传递消息。

生成一个单文档应用程序

  • 为应用程序添加“延时”菜单项,其 ID 为 ID_PRIME
  • 利用类向导添加消息处理函数,并添加如下代码
void CLi10_2View::OnPrime()
{
	// TODO: 在此添加命令处理程序代码
	HWND hWnd = GetSafeHwnd();   //获取当前窗口指针句柄
	AfxBeginThread(Calculateprime, hWnd, THREAD_PRIORITY_BELOW_NORMAL, 0); //启动线程
}

//工作者线程/*
CWinThread * AfxBeginThread(AFX_THREADPROC pfnThreadProc,
    LPVOID pParam, int nPriority = THREAD_PRIORITY_NORMAL,
    UINT nStackSize = 0, DWORD dwCreateFlags = 0,
    LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);
其中,参数pfnThreadProc是一个指向线程函数的指针,参数pParam的类型与线程函数参数类型完全一致,
该参数为启动线程时传递给线程函数的入口参数。其他几个参数用于设置线程的优先级、线程的堆栈大小、
创建时是否立即运行及线程的安全属性,这四个参数通常使用默认值。*/
  • 在.h 文件的类外面声明全局线程函数并添加自定义消息 ID
#define WM_CALCULATE  WM_USER + 100
UINT Calculateprime(LPVOID pPrame);
  • 在.h 文件的消息映射部分加入如下代码 
afx_msg LONG OnThreadEnd(WPARAM wParam, LPARAM lParam);

 

  • 在.cpp 文件的消息映射下面加入如下代码,并在文件起始位置定义一个全局变量 n 用于线程间的通信
ON_MESSAGE(WM_CALCULATE, OnThreadEnd)

  • 在.cpp 文件中定义线程函数
UINT Calculateprime(LPVOID pParam)
{
	Sleep(3000);
	n = 100;
	::PostMessage((HWND)pParam, WM_CALCULATE, n, 0);
	return 0;
}
  • 在.cpp 文件中添加消息处理函数 OnThreadEnd()。
LONG CLi10_2View::OnThreadEnd(WPARAM wParam, LPARAM lParam)
{
	CString str;
	str.Format("The Prime Numbers is %d.", n);
	MessageBox(str);
	return 0;
}
  • 编译、链接并运行程序。选择“延时”菜单命令,工作线程执行完毕后,自动显示下图结果
程序运行界面
点击延时后 3S 结果

相应程序代码下载: 链接:https://pan.baidu.com/s/1cmRETFCUuNMKKuyjR6EcMQ  密码:d20a

https://download.csdn.net/download/qq_41291253/12013646 有 CSDN 会员的伙伴,还望支持下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章