我做了一个对话框程序,它的主要功能是向串口不停的收发数据,因为数据量太大,以至于把程序最小化后不能恢复过来(此程序经常占用CPU 95 % 以上)。所以我决定使用多线程,让一个线程来负责串口通信,让主线程进行数据处理。在没有使用多线程的时候,我的思路是这样的。
有一个大的for循环
for(i...)
{
...串口通信; ...数据处理;
}
按照这个思路我已经做好了程序。
现在我使用多线程技术,开了一个辅助线程,让辅助线程进行串口通信,主线程进行数据处理。但这样做带来一个问题,因为在每轮for循环里面,数据处理必须要等串口通信完成才行(我使用WaitForSingleObject(g_Event.m_hObject, INFINITE);),而每轮的串口通信数据量又特别大,这就导致主线程每轮都要等很长时间,那就使得“把程序最小化后不能恢复过来”。请问该怎么解决?
是要开两个辅助线程,一个进行串口通信,一个进行数据处理么?这样做,我要对原程序做较大的修改,比较复杂。如果依然仅开一个辅助线程,让这个辅助线程完成后通过消息通知主线程,应该怎么做啊?能不能在我的原来的大for循环的结构里面做小小修改就可以啊?谢谢!
有一个大的for循环
for(i...)
{
...串口通信; ...数据处理;
}
按照这个思路我已经做好了程序。
现在我使用多线程技术,开了一个辅助线程,让辅助线程进行串口通信,主线程进行数据处理。但这样做带来一个问题,因为在每轮for循环里面,数据处理必须要等串口通信完成才行(我使用WaitForSingleObject(g_Event.m_hObject, INFINITE);),而每轮的串口通信数据量又特别大,这就导致主线程每轮都要等很长时间,那就使得“把程序最小化后不能恢复过来”。请问该怎么解决?
是要开两个辅助线程,一个进行串口通信,一个进行数据处理么?这样做,我要对原程序做较大的修改,比较复杂。如果依然仅开一个辅助线程,让这个辅助线程完成后通过消息通知主线程,应该怎么做啊?能不能在我的原来的大for循环的结构里面做小小修改就可以啊?谢谢!
解决方案 »
- 刚学MFC,在客户区滚动输出一段文本串
- 关于非模态对话框创建和销毁的一个疑问,求解答~
- 大家帮我看下CEdit的代码,为什么显示不出来呢
- 求一个简单的邮件客户端源代码
- 求解:DCOM/COM+/.NET的关系
- 比较WSAEventSelect异步模型和重叠模型,有什么不同?请参与
- 压缩的一个问题[在线]
- Rigel(猎户座-参宿七) 辞职了,高兴啊,散分了!(6)
- 如何解决CListCtrl控件的选项被选择的消息问题
- 如何是图片中的某种颜色透明呢?
- 用socket编写一个网络即时聊天小程序出现的问题
- 执行WaitCommEvent(m_hCom,&dwMask,&os)后,用GetLastError()却得到返回ERROR_INVALID_PARAMETER?
WaitForSingleObject(g_Event.m_hObject, 0);
没有信号就继续别的事情,过段时间再查询一下。或者线程里数据接收完成向界面线程发送一个消息。
参考:
http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=435
实际上是不行的,for(i...)
{
...串口通信; WaitForSingleObject(g_Event.m_hObject, 0);
...数据处理;
}如果这样,就会在没有等到串口通信完成就进行数据处理了。这样是不行的。谢谢你!
我发现使用消息的话,会破坏for大循环。其实我这个for大循环是很复杂的,把串口通信部分用一个辅助线程来处理还是比较容易的,对原来的程序修改不大。如果要改成辅助线程发消息给主线程,那么对原来的代码改动很大。有没有对for大循环改动不大的方法啊?谢谢你!
{
...串口通信; WaitForSingleObject(g_Event.m_hObject, 0);
if(hasData)
{
...数据处理;
}
}
使用 if(hasData)也不行,因为那样就会进入循环的下一轮,这样也会把数据处理的顺序搞错。我想问问,有没有这样的wait,在主线程里面使用它,既可以让主线程停在那里不动,有可以让主线程不僵?
GoldenSword(金错刀)
使用 if(hasData)也不行,因为那样就会进入循环的下一轮,这样也会把数据处理的顺序搞错。我想问问,有没有这样的wait,在主线程里面使用它,既可以让主线程停在那里不动,有可以让主线程不僵?
===========================================这样不会进入循环下一轮的,只有处理完成后线程才会继续往下走,你可以试试看。如果想让程序继续向下走的话,就用 PostMessage(),这样不会阻塞线程
你说的方法,好像还是不行,我试过了。现在我写了一个简单的程序,这里说出它的步骤。
1。做了一个Test的对话框程序,在上面放了一个按钮
2。在.cpp文件里面
CEvent g_e;
UINT Thr(LPVOID pParam)//线程函数
{
Sleep(10000);
g_e.SetEvent();
return 0;
}BOOL CTestDlg::OnInitDialog()
{
......
AfxBeginThread(Thr, NULL);
return TRUE; // return TRUE unless you set the focus to a control
}
void CTestDlg::OnButton1()
{
// TODO: Add your control notification handler code here
int i;
WaitForSingleObject(g_e.m_hObject, 0);
i=1;
i=2;
i=3;
}
在WaitForSingleObject这句设置断点。发现,单步运行时候,根本没有任何等待时间,就会运行到i=1;处,再单步,变量i就给赋值1了。我如果用WaitForSingleObject(g_e.m_hObject, INFINITE);
单步运行,确实会在WaitForSingleObject等待10秒钟,
而直接运行(非调试),点击按钮主程序会出现僵的情况。我实际希望的情况是,在wait处等10秒,而主程序有不僵。
jjiaming(阿熊),也谢谢你,不知道你对我现在的说法是否很清楚,请帮助,谢谢!
{
...串口通信; ...数据处理;
}
按照这个思路我已经做好了程序。
===========================================应该适当让cpu休息
在串口通信中使用sleep(10),你自己调试吧。
我就写过串口程序,适当加sleep,cpu会空闲很多,而且比没加处理速度基本一样。
GoldenSword(金错刀)
使用 if(hasData)也不行,因为那样就会进入循环的下一轮,这样也会把数据处理的顺序搞错。我想问问,有没有这样的wait,在主线程里面使用它,既可以让主线程停在那里不动,有可以让主线程不僵?
===============================
在主线程中使用wait 而不僵是不可能的。
只能使用
peekMessage
具体你查查相当于vb中的DoEvent,使进程可响应消息(在主线程使用Wait,会阻塞主线程)
在主线程组塞,发PostMessage是不起作用的,主线程根本不能响应,让主线程停下来而又不组塞消息唯一办法使用windows 消息循环PeekMessage你查查Msdn吧,我没时间给你贴代码了。
{
if(m_bReceiveComplete|| m_bCancel)//接收完成或取消接收则跳出循环
break;
else
{
//进入消息循环,使主线程序响应Windows 消息
while(PeekMessage(&msg,0,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
//让主线程休息,可自己调节时间。
Sleep(1000);
}