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 编辑 ] 有专门的工具来测试。
用strace,来打印一下你的调用过程,查看耗在了哪里。
http://sourceforge.net/projects/strace/
http://en.wikipedia.org/wiki/Strace
希望有所帮助。 如果是CPU100%,一般是死循环造成的哦。
多一些ACE_DEBUG();逐渐缩小范围,你就会找到了。 多谢, top命令把WCHAN选项打印出来后发现睡在futex_wait这个函数上,可能是锁竞争吧. winston,freeeyes
你们在用ACE_Dev_Poll_Reactor时会出现CPU过高的情况吗? 我把数据库访问部分关掉. 就留下网络收数据这一块. 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 编辑 ] 在网上找到了这篇文章: 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 编辑 ] 我现在正在使用devpoll,做了一个类似web的服务器。
大概同时连接不会超过200个,现在cpu TOP差不多在10%左右。
具体要看你的代码,理论上锁竞争也不会导致cpu 100%。
贴出你的代码看看。 我用的是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;
} 换成了ACE_TP_Reactor后cpu正常.
页:
[1]
2