大家的接收线程是怎么实现的啊?怎么我的接收线程消耗CPU资源这么大啊?

B2China 2004-05-02 01:39:27
我的服务程序在一个客户端接入以后就开一个接收线程,负责接收它的数据。
在此期间客户机保持和服务器的连接。

实际运行时,发现这个接收线程一运行,CPU利用率达到100%,根本接收不了其他的连接,请问大家怎么处理接收线程的?怎么改善接收线程的性能?


// 接收数据线程如下:
DWORD WINAPI RecvThread(LPVOID lParam)
{
int Socket;
Socket= (int )lParam;
fd_set fdRead;
struct timeval tmvTimeout={0L,100L};
char RecvBuf[256];

while (TRUE)
{
// 初始化
FD_ZERO(&fdRead);
FD_SET(Socket,&fdRead);
int ret = select(0,&fdRead,NULL,NULL,&tmvTimeout);
if (ret == SOCKET_ERROR)
{
printf("Select() Socket error: %d..\n",GetLastError ());
continue;
}
else if (ret > 0)
{
if (FD_ISSET(Socket,&fdRead))
{ // 有数据可读
nRecv= recv (Socket, RecvBuf, sizeof( RecvBuf), 0);
if (nRecv == SOCKET_ERROR)
{ // 读数据出错
printf("Recv socket error: %d..\n",GetLastError());
}
else
if (nRecv == 0)
{ // 客户端断开连接
printf("remote socket closed..\n");
closesocket(Socket);
break;
}

// 数据读入成功,做数据处理
printf("Successfully receive %d bytes..\n"),nRecv);
ProcessData(RecvBuf);
}
}
}
printf("Recv thread exit with 0..\n");
return 0;
}
...全文
44 10 点赞 打赏 收藏 举报
写回复
10 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
danscort2000 2004-05-04
加SLEEP( )控制
或者用消息EVENT通知。
WHILE( )
循环对CPU的消耗太巨大了,一定要有措施来主动交出CPU时间段
  • 打赏
  • 举报
回复
UDX协议 2004-05-03
BOOL CClientOverlappedSock::OnRead()
{
if(!IsConnected())
return false;
DWORD dwTransbit = 0;
DWORD Resv = 0;
DWORD dwFlag = 0;
WSABUF buffer;
BOOL bQuery = false;
int state = 0;

bQuery = WSAGetOverlappedResult( m_RecSocket, &ConnectedSocketOverlapped,
&dwTransbit,false,&dwFlag);
if(bQuery)
{
if(dwTransbit == 0)
{
OnClose();
return true;
}
while(1)
{
if( rPag.len - sizeof(PAG) == DataRes)
{
////
Work();
Reset();
////

buffer.buf = (char*)& rPag;
buffer.len = sizeof(PAG);
state = WSARecv( m_RecSocket,&buffer,1,&Resv,
&dwFlag, &ConnectedSocketOverlapped,NULL);

if(state == 0)
{
continue;
}else
{
DWORD err = WSAGetLastError();
if(err != WSA_IO_PENDING)
{
TRACE1("erro code1 %d\n",err);
OnClose();
return false;
}else
{
if(ERROR_IO_PENDING == err)
{
return true;
}
}
}
}else
if( rPag.len - sizeof(PAG) - DataRes > 0)
{
if(!m_bReadPending)
{
if(buff == NULL)
{
buff = new char [ rPag.len - sizeof(PAG)];
memset( buff,0, rPag.len - sizeof(PAG));
buffer.buf = buff;
buffer.len = rPag.len - sizeof(PAG);
}

Resv = 0;
buffer.len = rPag.len - sizeof(PAG) - DataRes;
buffer.buf = buff + DataRes;
state = WSARecv( m_RecSocket,&buffer,1,&Resv,
&dwFlag, &ConnectedSocketOverlapped,NULL);
if(state == 0)
{
DataRes+=Resv;
continue;
}else
{
DWORD err = WSAGetLastError();
if(err != WSA_IO_PENDING)
{
TRACE1("erro code2 %d\n",err);
OnClose();
return false;
}else
{
if(ERROR_IO_PENDING == err)
{
m_bReadPending = true;
return true;
}
}
}
}else
{
DataRes+=dwTransbit;
}
}
if(!IsConnected())
return 0;
Sleep(1);
TRACE1("RES DATA IS %u\n",DataRes);
}
}else
{
DWORD err = WSAGetLastError();
if(err != ERROR_IO_INCOMPLETE)
{
OnClose();
TRACE1("erro code3 %d\n",err);
return false;
}else
return true;
}
return true;
}
吐血回贴!
当没有数据来时,根本不占用cpu.
  • 打赏
  • 举报
回复
max_xy 2004-05-02
刚刚觉得用SETTIMER來做,不用while循环。不知道cpu会不会降低一点。来做个测试。
  • 打赏
  • 举报
回复
酷比程序 2004-05-02
我也是用While实现的,不过我只是在监听网络,代码差不多你看一下嘛,刚开始我也是CPU占用很高,后来加了一个return 就好了:
DWORD WINAPI LoopScanThread(LPVOID lpparam)
{
SOCKET ListenSocket=(SOCKET)lpparam;

sockaddr_in send;
int sendlen=sizeof(send);
CString aa2="----接收方最大允许连接数为10----";
AfxGetMainWnd()->SendMessageToDescendants(WM_LISTBOX,(WPARAM)aa2.GetBuffer(0),1);
aa2.ReleaseBuffer();

//接收方允许最大的连结数是10
int rc=listen(ListenSocket,10);

if(rc==SOCKET_ERROR)
{
CString a5="----创建监听socket失败,请检查网络后重试----";
AfxGetMainWnd()->SendMessageToDescendants(WM_LISTBOX,(WPARAM)a5.GetBuffer(0),1);
a5.ReleaseBuffer();
::MessageBeep(MB_ICONHAND);
return 0;
}

CString aa3="----创建监听socket成功,开始监听网络----";
AfxGetMainWnd()->SendMessageToDescendants(WM_LISTBOX,(WPARAM)aa3.GetBuffer(0),1);
aa3.ReleaseBuffer();
::MessageBeep(MB_ICONASTERISK);
while(1)
{
SOCKET ConnectSocket;

ConnectSocket=accept(ListenSocket,(sockaddr*)&send,&sendlen);

if(ConnectSocket==INVALID_SOCKET)
{
CString a="----接收发送方请求失败----";
AfxGetMainWnd()->SendMessageToDescendants(WM_LISTBOX,(WPARAM)a.GetBuffer(0),1);
a.ReleaseBuffer();
::MessageBeep(MB_ICONHAND);
return -1;
}

CString a="----接收请求成功,连接已经建立----";
AfxGetMainWnd()->SendMessageToDescendants(WM_LISTBOX,(WPARAM)a.GetBuffer(0),1);
a.ReleaseBuffer();
//直到accept()成切返回,然后进入别一个线程,来接收文件消息
DWORD dwThread1;
::CreateThread(NULL,0,GetFileInfoThread,(LPVOID)ConnectSocket,0,&dwThread1);
}
return 0;
}
  • 打赏
  • 举报
回复
max_xy 2004-05-02
我的线程加了SLEEP,cpu利用率大概20%.但是假如一个客户端需要联接很多个客户端,每个客户端对服务端的联接都使用一个线程的话,CPU的利用率就会很高。不知道能不能不用while而实现同样的功能。
  • 打赏
  • 举报
回复
max_xy 2004-05-02
楼上的,请问怎么样处理select错误呢,按照您的意思。给点代码如何
  • 打赏
  • 举报
回复
UDX协议 2004-05-02
一种方法是加sleep(1).在while里面。
另一个方法是,是用事件方式。

你的接收处理方法有问题
if (ret == SOCKET_ERROR)
{
printf("Select() Socket error: %d..\n",GetLastError ());
continue;//很显然,这里需要Getlastererro看看一下错误原因,这样,在不需要的时候,跳出循环。
}

  • 打赏
  • 举报
回复
elusion 2004-05-02
sleep一下
  • 打赏
  • 举报
回复
我在串口通信中使用的是事件的触发方式,所以只有数据来的时候,才触发接收,
  • 打赏
  • 举报
回复
B2China 2004-05-02
我是用whle(true),这个大循环来不停的监视客户端连接是否有数据可读的,可能是由于这个原因导致CPU利用率高的惊人。
  • 打赏
  • 举报
回复
相关推荐
发帖
网络编程
加入

1.8w+

社区成员

VC/MFC 网络编程
申请成为版主
帖子事件
创建了帖子
2004-05-02 01:39
社区公告
暂无公告