sugar 发表于 2010-5-11 15:19:24

ACE_Dev_Poll_Reactor(5.7.0)导致CPU占有率高?

做了一个服务器程序,客户端向服务器请后, cpu利用100%,然后就下不来(后面就没有向服务器发送请求了),如何来诊断,是那什么操作占用cpu.

top - 15:10:42 up4:32,2 users,load average: 8.45, 8.55, 8.64
Tasks: 124 total,   2 running, 122 sleeping,   0 stopped,   0 zombie
Cpu0: 26.9%us, 73.1%sy,0.0%ni,0.0%id,0.0%wa,0.0%hi,0.0%si,0.0%st
Cpu1: 30.2%us, 69.8%sy,0.0%ni,0.0%id,0.0%wa,0.0%hi,0.0%si,0.0%st
Cpu2: 25.9%us, 74.1%sy,0.0%ni,0.0%id,0.0%wa,0.0%hi,0.0%si,0.0%st
Cpu3: 24.7%us, 75.3%sy,0.0%ni,0.0%id,0.0%wa,0.0%hi,0.0%si,0.0%st
Mem:   4089744k total,   514092k used,3575652k free,    52508k buffers
Swap: 10481656k total,      0k used, 10481656k free,   184456k cached
PID USER      PRNIVIRTRESSHR S %CPU %MEM    TIME+COMMAND                                                                                                            
2496 bg      20   0430m41m 6984 S   931.098:52.73 APP1                                                                                                         
2455 bg      20   0465m61m 6984 S   751.599:55.35 APP2                                                                                                   
2507 bg      20   0430m49m 6880 S   751.296:21.07 APP3                                                                                                      
2444 bg      20   0401m27m 6984 S   580.792:10.49 APP4                                                                                                   
2518 bg      20   0412m47m 6880 S   511.292:22.14 APP5                                                                                                      
2403 bg      20   0358m 9.9m 6880 S   490.292:06.77 APP6                                                                                                         
2751 bg      20   02544 1212928 R    00.0   0:00.04 top                                                                                                                  
1261 bg      20   05772 3164 1584 S    00.1   0:00.44 bash                                                                                                               
1281 bg      20   08280 1508908 S    00.0   0:00.21 sshd                                                                                                               
1282 bg      20   04136 2868 1440 S    00.1   0:00.15 bash                                                                                                               
1346 bg      20   03104 2036696 S    00.0   0:00.32 sftp-server                                                                                                         
2551 bg      20   02544 1216928 S    00.0   0:18.53 top

[ 本帖最后由 sugar 于 2010-5-12 16:26 编辑 ]

winston 发表于 2010-5-11 16:27:20

有专门的工具来测试。
用strace,来打印一下你的调用过程,查看耗在了哪里。
http://sourceforge.net/projects/strace/
http://en.wikipedia.org/wiki/Strace
希望有所帮助。

freeeyes 发表于 2010-5-11 16:45:27

如果是CPU100%,一般是死循环造成的哦。
多一些ACE_DEBUG();逐渐缩小范围,你就会找到了。

sugar 发表于 2010-5-12 10:31:31

多谢, top命令把WCHAN选项打印出来后发现睡在futex_wait这个函数上,可能是锁竞争吧.

sugar 发表于 2010-5-12 11:44:20

winston,freeeyes
你们在用ACE_Dev_Poll_Reactor时会出现CPU过高的情况吗?

sugar 发表于 2010-5-12 14:42:17

我把数据库访问部分关掉. 就留下网络收数据这一块. cpu也是达到100% . 我感觉到ACE_Dev_Poll_Reactor可能就存在这个问题.我写个ACE_Dev_Poll_Reactor的简单的echo DEMO. 开了20个线程运行事件循环, top命令显示如下:
top - 15:25:44 up1:11,2 users,load average: 1.13, 1.14, 2.63
Tasks: 119 total,   1 running, 118 sleeping,   0 stopped,   0 zombie
Cpu0:4.0%us,6.0%sy,0.0%ni, 90.0%id,0.0%wa,0.0%hi,0.0%si,0.0%st
Cpu1:1.0%us,2.3%sy,0.0%ni, 96.7%id,0.0%wa,0.0%hi,0.0%si,0.0%st
Cpu2: 15.6%us, 29.8%sy,0.0%ni, 54.6%id,0.0%wa,0.0%hi,0.0%si,0.0%st
Cpu3: 17.4%us, 31.7%sy,0.0%ni, 50.9%id,0.0%wa,0.0%hi,0.0%si,0.0%st
Mem:   4089744k total,   232004k used,3857740k free,    11924k buffers
Swap: 10481656k total,      0k used, 10481656k free,   150856k cached
PID USER      PRNIVIRTRESSHR S %CPU %MEM    TIME+WCHAN   COMMAND                                                                                                   
1878 bg      20   0167m 1916 1116 S1160.010:02.20 futex_wai acepoll_demo                                                                                             
1899 bg      20   02544 1216936 S    00.0   0:01.67 poll_sche top                                                                                                      
1213 bg      20   05680 3088 1584 S    00.1   0:00.23 wait      bash                                                                                                      
1234 bg      20   08280 1496908 S    00.0   0:00.09 poll_sche sshd                                                                                                      
1235 bg      20   04148 2876 1440 S    00.1   0:00.12 wait      bash                                                                                                      
1275 bg      20   03104 2024696 S    00.0   0:00.15 poll_sche sftp-server                                                                                                
1907 bg      20   02540 1216936 R    00.0   0:00.04 -         top


然后我把ACE_Dev_Poll_Reactor换成ACE_TP_Reactor后,cpu的占有率基本就是0

[ 本帖最后由 sugar 于 2010-5-12 15:48 编辑 ]

sugar 发表于 2010-5-12 16:13:46

在网上找到了这篇文章: http://stevehuston.wordpress.com/2010/02/05/resolving-the-cpu-bound-ace_dev_poll_reactor-problem-and-more/
说是在5.7.7解决了这个问题. 但是我还没有去官网上去看.
google 关键字: CPU-bound ACE_Dev_Poll_Reactor

不小心看到了本站的这篇文章: http://www.acejoy.com/space/html/87/t-1787.html 也是对ACE_Dev_Poll_Reactor问题的讨论.

[ 本帖最后由 sugar 于 2010-5-12 16:24 编辑 ]

freeeyes 发表于 2010-5-12 18:29:56

我现在正在使用devpoll,做了一个类似web的服务器。
大概同时连接不会超过200个,现在cpu TOP差不多在10%左右。
具体要看你的代码,理论上锁竞争也不会导致cpu 100%。
贴出你的代码看看。

sugar 发表于 2010-5-13 12:27:05

我用的是5.7.0版本的.
demo如下:

// main.cpp

#include <ace/ACE.h>
#include <ace/SOCK_Acceptor.h>
#include <ace/Acceptor.h>
#include <ace/Thread_Manager.h>
#include <ace/Dev_Poll_Reactor.h>
#include "APPS_Service_Handler.h"
ACE_THR_FUNC_RETURN apps_service_event_loop(void *arg)
{
ACE_Reactor *reactor = static_cast<ACE_Reactor *> (arg);
if (reactor)
{
reactor->owner (ACE_OS::thr_self ());
reactor->run_reactor_event_loop ();
}
return 0;
}
int ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
ACE::init();

// Make sure we ignore SIGPIPE
sigset_t sigsetNew;
sigset_t sigsetOld;
ACE_OS::sigemptyset (sigsetNew);
ACE_OS::sigaddset (sigsetNew, SIGPIPE);
ACE_OS::sigprocmask (SIG_BLOCK, sigsetNew, sigsetOld);
ACE_Dev_Poll_Reactor dev_reactor;
dev_reactor.restart(1);
ACE_Reactor reactor(&dev_reactor);

ACE_Reactor::instance(&reactor);
//////////////////////////////////////////////////////////////////////////
// 启动服务
int nRet = -1;
// 客户端
ACE_Acceptor<CAPPServiceHandler, ACE_SOCK_Acceptor> acceptor;
ACE_INET_Addr addr_listen_client(9011);
if(0 != (nRet = acceptor.open(addr_listen_client)))
return nRet;
ACE_Thread_Manager::instance()->spawn_n(20,apps_service_event_loop,ACE_Reactor::instance());
return ACE_Thread_Manager::instance()->wait();
ACE::fini();
return 0;
}


// APPServiceHandler.cpp
int CAPPServiceHandler::handle_input(ACE_HANDLE fd /* = ACE_INVALID_HANDLE */)
{
ssize_t msg_len = 8 * 1024 + 1;
ssize_t recv_len = 0;
char msg = {0};
ACE_Time_Value timeout(5);
recv_len = peer().recv(msg, msg_len,&timeout);
if (recv_len > 0 && recv_len < msg_len)
{
std::string strResult = msg;
if (!strResult.empty())
{
   peer().send_n(strResult.c_str(),strResult.length(),&timeout);
}
}
else if (-1 == recv_len)
{
// 超时
if (ETIME == errno)
{
}
}
else if (0 == recv_len) // 客户端关闭连接
{
return -1;
}
else if (recv_len == msg_len) // 数据包长度超过了最大长度
{
return -1;
}
return -1;
}

sugar 发表于 2010-5-14 11:27:34

换成了ACE_TP_Reactor后cpu正常.
页: [1] 2
查看完整版本: ACE_Dev_Poll_Reactor(5.7.0)导致CPU占有率高?