在软件项目里有三个模块,分别为
一个应用模块(处理数据)
一个显示模块(屏幕)
一个通信模块(与主机通信)
每个模块都会继承WINDOW收发通信模块基类创建一个属于自己的子窗口,然后在窗口的消息处理函数中对收到的消息进行处理。
在其中一个测试过程中,当通信模块收到主机命令然后向应用模块发送指令,应用模块执行完后,应用模块会向通信模块发送指令执行成功消息。调用
ret = ::SendMessageTimeout(hRecvWnd,// handle to window
WM_COPYDATA,// message type
(WPARAM)hSendWnd,// first message parameter
(LPARAM)&cds,// second message parameter
SMTO_BLOCK,// send options
3000,// time-out duration
&dwResult);// return value for synchronous call
没想到最后执行超时了2次,最后一次才成功。延迟了9秒。
原因是当应用模块发送消息后,基类窗口处理函数调用的接收到的消息处理动作阻塞住了。
解决阻塞有3种方法
1. 把接受到的消息内容,先拷贝起来,然后直接给发送信息的窗口返回消息处理,然后继续对接受到的消息进行处理.
2. 每收到一个消息,创建一个线程,把收到的消息内容存储起来,然后在线程里对接受到的消息进行处理。
3. 把所有接受到的消息内容,拷贝到队列里,然后对队列里的接受到的消息进行处理
最后我选择了用线程,因为这个比较简单,而且线程数量也不多,释放也简单。
原来的窗口消息处理函数为
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COPYDATA:
COPYDATASTRUCT* cds = (COPYDATASTRUCT*)lParam;
if ((cds!=NULL)&&(m_ipc!=NULL))
{
//m_ipc为CIPC的类对象,
m_ipc->OnReceive(m_csSendWndTile,cds->dwData,cds->lpData,cds->cbData);
}
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
修改后的窗口消息处理函数为:
UINT Thread_Process(LPVOID lpContext)
{
COPYDATASTRUCT* cds = new COPYDATASTRUCT;
memcpy(cds,(COPYDATASTRUCT*)lpContext,sizeof(COPYDATASTRUCT));
if ((cds!=NULL)&&(g_pIPC!=NULL))
{
g_pIPC->OnReceive("",cds->dwData,cds->lpData,cds->cbData);
}
delete []cds;
AfxEndThread(0);
return 0;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COPYDATA:
CString appName = AfxGetAppName();
//因为只有应用模块发送消息的时候才会阻塞,而且如果显示模块也用线程的话,那每个线程都带有一个显示屏幕。
//不好处理。通信模块需要自己给自己发送消息,所以如果创建线程的后,就涉及到线程间通信的问题,所以这两个
//模块没有用线程。实际证明也不需要。
if (appName.Compare("通信模块")==0 || appName.Compare("显示模块")==0) //
{
COPYDATASTRUCT *cds = (COPYDATASTRUCT*)lParam;
if ((cds!=NULL)&&(g_pIPC!=NULL))
{
g_pIPC->OnReceive("",cds->dwData,cds->lpData,cds->cbData);
}
}
else
{
AfxBeginThread(Thread_Process,(COPYDATASTRUCT*)lParam);
}
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
分享到:
相关推荐
来自VC知识库-代码仓库,使用GSM模块收发短消息,发短息像聊QQ一样,不过要运行此程序首先你得有GSM模块硬件设备。
使用多线程编写的收发消息Demo,参考时请对多线程和套接字做基本的了解
一个可扩展的聊天平台隧道 Bot 框架,目前支持在 Telegram 收发微信消息。基于 Python 3。.zip,一个可扩展的消息隧道聊天机器人框架。在多个平台之间传递消息,并远程控制您的帐户。
可以实现利用GSM模块收发短消息,采用TEXT方式收发操作,实现140字符的收发。
基于多线程的QUdpSocket收发数据程序,界面上可以输入目标ip、port,与网络调试助手调试ok 欢迎下载,并指出程序中的问题,谢谢
多线程socket文件传输支持断点续传收发消息点对多点 使用阻塞方式的socket。经过测试,程序比较稳定,可在此基础上进行后续开发。
这个工具可以收发JMS的消息,对消息中间件进行性能测试
sscom模拟串口收发消息
java做的短消息平台通过网络进行收发信息平台
一个C#实现IBM WebSphere MQ 消息收发的实例,包含 发送接收等. 使用的时候只需要修改 appconfig 文件的内容即可. 如有问题.请留言
用PHP收发RabbitMQ消息,分为send.php存入消息队列和get.php从消息队列中取出并处理。取出采用阻塞模式,需要在命令行下运行。
刚学netty ,写了一个基于netty的服务器客户端收发消息代码,功能非常简单,服务器每3秒向服务器发消息,服务器再把消息反给你。简单收1分,希望大家谅解。
FPGA串口多字节收发,含modelsim仿真
基于Linux的SNMP消息收发的实现.pdf
C++多线程SOCKET收发纯手工打造,网上的例子和解释都不行~既可以学习多线程操作,又可以实现SOCLET编程
nRF24L01无线模块实现一对一、一对多、多对一收发程序 简单实用 明了
使用阻塞方式的socket,使用多线程,有较高的性能.在局域网中测试达到极限速度.支持断点续传.服务端可同时接收多个文件.传输文件的同时可以发送网络消息.各位如果发现bug,请与我联系,以便做得更好:hongxing777@msn....
delphi进程间消息收发 通过获取窗口句柄发送tcopydata消息 附带一些小参数
https://blog.csdn.net/AN195/article/details/80657130 用socket服务端和多线程实现可以连接多个客户端并同时收发的功能。 这里带一个很简单的多线程客户端
CAN两个节点收发(C51+SJA1000) CAN两个节点收发(C51+SJA1000)