您的位置:首页 > 其它

多个窗口收发WINDOW消息阻塞的一点思考

2013-11-22 00:04 453 查看
在软件项目里有三个模块,分别为

一个应用模块(处理数据)

一个显示模块(屏幕)

一个通信模块(与主机通信)

每个模块都会继承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);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐