开启一个线程读串口数据,cpu 100%?

maojian2011 2010-08-12 12:39:17
孙鑫老师十五章最后一个例子,多线程+网络编程,线程函数里有一个while死循环,为什么cpu 不是100%,是不是因为recvfrom是阻塞的,程序运行到这就停了,等到线程的时间用完了,就回到主线程,不会一直占用cpu?我写了一个读串口的线程,用的是同步,为什么cpu 是100%,函数如下:
UINT CTestDlg::ComProc(LPVOID pParam)
{
HWND Hdlg=(HWND)pParam;
while(1)
{
//Sleep(1);
char str[1024];
memset(str,'\0',1024);
DWORD wCount=0;//读取的字节数
BOOL bReadStat;

bReadStat=ReadFile(m_hCom23,str,1024,&wCount,NULL);

if(bReadStat)//*/
if(wCount>0)
{
::SetDlgItemText(Hdlg,IDC_EDIT_RECV,str);
}
}
return 0;
}
...全文
457 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
pDaren 2010-08-29
  • 打赏
  • 举报
回复
这里涉及到CPU时间片的问题。
当调用Sleep(1) 时当前线程就会挂起,去调用其它线程。
如果不调用Sleep函数,这个线程就会一直执行到时间片结束为止。


recvfrom函数里面应该也有类似于Sleep的函数,你的例子可以证明。


。。。我不知道这样说,有没有把问题写清楚。
xu342906691 2010-08-20
  • 打赏
  • 举报
回复
没有加Sleep(10),CPU肯定可以正常运行,只不过大部分的CPU一直在处理你这个循环中的语句,所以CPU会是%100,如果你这个程序最小化,再去看看其他进程就会发现很卡。
使用Sleep()可以,也可以使用WaitForSingleObject()这样CPU的使用率也不会那么高
maojian2011 2010-08-15
  • 打赏
  • 举报
回复
问题解决了。通过超时设置,将ReadFile设置成一直等待,就和孙鑫老师的例子对上了,cpu也不会占用100%。Sleep()这句可以去掉!超时设置如下:
TimeOuts.ReadIntervalTimeout=MAXDWORD;//读超时,有数据立即返回,
TimeOuts.ReadTotalTimeoutMultiplier=MAXDWORD;//没有数据一直等待,
TimeOuts.ReadTotalTimeoutConstant=10;//超时10ms后返回
如果设置成下面这样,ReadFile是立即返回,造成cpu占用的比较厉害,就会出现100%的问题
TimeOuts.ReadIntervalTimeout=MAXDWORD;//读超时,立即返回
TimeOuts.ReadTotalTimeoutMultiplier=0;//
TimeOuts.ReadTotalTimeoutConstant=0;//
wltg2001 2010-08-12
  • 打赏
  • 举报
回复
当然100%了,while(1)一直在循环啊
大大怪老张 2010-08-12
  • 打赏
  • 举报
回复
很可能跟串口的设置有关。
你可以看看每次 ReadFile 的返回值是什么,如果你的串口不停的过来,cpu占用应该还是蛮高的。

另外你可以把循环里面的变量声明放到循环外面去,优化一下。
maojian2011 2010-08-12
  • 打赏
  • 举报
回复
加上Sleep(10);能解决cpu 100%的问题,我现在不明白的是,为什么下面这段代码,没加Sleep,cpu也能正常运行
wysbk002 2010-08-12
  • 打赏
  • 举报
回复
我的意思是
吧// 去掉!
maojian2011 2010-08-12
  • 打赏
  • 举报
回复
这是孙鑫vc教学视频的例子,cpu运行很正常
DWORD WINAPI CChatDlg::RecvProc(LPVOID lpParameter)
{
SOCKET sock=((RECVPARAM*)lpParameter)->sock;
HWND hwnd=((RECVPARAM*)lpParameter)->hwnd;
delete lpParameter; //视频讲述时,遗忘了释放内存的操作。sunxin

SOCKADDR_IN addrFrom;
int len=sizeof(SOCKADDR);

char recvBuf[200];
char tempBuf[300];
int retval;
while(TRUE)
{
retval=recvfrom(sock,recvBuf,200,0,(SOCKADDR*)&addrFrom,&len);
if(SOCKET_ERROR==retval)
break;
sprintf(tempBuf,"%s说: %s",inet_ntoa(addrFrom.sin_addr),recvBuf);
::PostMessage(hwnd,WM_RECVDATA,0,(LPARAM)tempBuf);
}
return 0;
}
wltg2001 2010-08-12
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 maojian2011 的回复:]
楼上,不是很明白你的意思。
本来//Sleep(1); 这句就加着注释呢,还怎么去掉
[/Quote]
他的意思就是让你将注释去掉,去掉注释应该就不会100%了
Simao 2010-08-12
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 maojian2011 的回复:]
楼上,不是很明白你的意思。
本来//Sleep(1); 这句就加着注释呢,还怎么去掉
[/Quote]
如果不想CPU 占用100% while(1)循环中没有WaitForXXXObject()等待的话,一定要加Sleep(XX),否则程序一直在跑,系统资源一直占用着,不知道楼主明白了没...
浅蓝马 2010-08-12
  • 打赏
  • 举报
回复
看你像是要实现串口有数据的话马上进行处理,
不过我觉得你使用异步方式来读取数据应该就可以了,
不知道为什么一定要以一个循环来读数据。
或者有什么特殊需求?
maojian2011 2010-08-12
  • 打赏
  • 举报
回复
楼上,不是很明白你的意思。
本来//Sleep(1); 这句就加着注释呢,还怎么去掉

wysbk002 2010-08-12
  • 打赏
  • 举报
回复
//Sleep(1); 去掉就行了
因为是死循环 使用就100%了
类似
while(1)
{

}

//如果你是双核计算机 是50%

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧