亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問(wèn)板塊 發(fā)新帖
查看: 4430 | 回復(fù): 3
打印 上一主題 下一主題

父進(jìn)程listen,子進(jìn)程epoll監(jiān)聽(tīng)事件的問(wèn)題,各位高手請(qǐng)進(jìn)。 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2011-04-23 12:23 |只看該作者 |倒序?yàn)g覽
本帖最后由 oscarzhou 于 2011-04-23 12:33 編輯

設(shè)計(jì)的一個(gè)server,開(kāi)始是單進(jìn)程模式的,2w/s的訪問(wèn)量沒(méi)有問(wèn)題。但為了充分利用多cpu,想把它改成多進(jìn)程方式。

改動(dòng)不大,主要就是父進(jìn)程先創(chuàng)建listen對(duì)象,監(jiān)聽(tīng)端口,然后fork子進(jìn)程,每個(gè)子進(jìn)程創(chuàng)建自己的epoll,監(jiān)聽(tīng)listen_fd、accept_fd,以及跟后臺(tái)各server交互的fd。

問(wèn)題來(lái)了:比如我們起4個(gè)子進(jìn)程(每個(gè)cpu一個(gè)),然后用10個(gè)線程客戶端去壓力測(cè)試,在開(kāi)始測(cè)試的時(shí)候,客戶端總會(huì)有少量的接收超時(shí),沒(méi)有收到應(yīng)答包。但是過(guò)一段事件之后,就會(huì)跑的比較平穩(wěn),沒(méi)有超時(shí),壓力也很固定。

調(diào)試的時(shí)候,關(guān)閉了到后臺(tái)各Server的交互,收到包之后,本地處理就回包,也會(huì)有少量的超時(shí)。

不知道這是怎么回事?靜待高手解答。不要告訴我換多線程,或者父進(jìn)程epoll監(jiān)聽(tīng)listen_fd的實(shí)現(xiàn),哥懂那個(gè),只是想明白這種設(shè)計(jì)范式下的問(wèn)題可能是什么原因。

另外,據(jù)說(shuō)linux 2.6內(nèi)核版本已經(jīng)解決了此設(shè)計(jì)模式下的驚群?jiǎn)栴},但是否會(huì)有消息亂序,即A子進(jìn)程的fd加入到了B子進(jìn)程的epoll事件里去。


簡(jiǎn)化的實(shí)例代碼如下:


  1. /* 單進(jìn)程可以監(jiān)聽(tīng)本地多端口,每個(gè)端口創(chuàng)建一個(gè)對(duì)象,用vector保存起來(lái),用于傳遞到子進(jìn)程里,每個(gè)子進(jìn)程去創(chuàng)建epoll監(jiān)聽(tīng)listen_fd */
  2. vector<CPollerObject*> g_listen_obj;


  3. int InitGlobalInstance(){
  4.         pid_t pid = getpid ();
  5.         int iRet;
  6.        
  7.         /* 啟動(dòng)epoll */
  8.         iRet = CPollerUnit::Ins()->Create(g_conf.m_epoll._maxfd, g_conf.m_epoll._timeout);
  9.         if( E_OK!=iRet ){
  10.                 fprintf(stderr, "Create Epoll Error:%d\n", iRet);
  11.                 return E_FAIL;
  12.         }
  13.         DEBUG_LOG("CPollerUnit Create Succ: %p", CPollerUnit::Ins());
  14.        
  15.         for( vector<CPollerObject*>::iterator it=g_listen_obj.begin(); it!=g_listen_obj.end(); it++){
  16.                 (*it)->EnableInput();
  17.                 (*it)->AttachPoller();
  18.         }
  19.        
  20.         /* 初始化內(nèi)存池管理 */
  21.         iRet = CMemPool::Ins()->Create(g_conf.m_session._bufSize);
  22.         if( E_OK!=iRet ){
  23.                 fprintf(stderr, "Create Epoll Error:%d\n", iRet);
  24.                 return E_FAIL;
  25.         }
  26.         DEBUG_LOG("CMemPool Create Succ: %p", CMemPool::Ins());

  27.         /* 初始化連接池 */
  28.         iRet = CTcpPoll::Ins()->Init(g_conf.m_session._max, g_conf.m_errReport._failCount, g_conf.m_errReport._timeInterval);
  29.         if( E_OK!=iRet ){
  30.                 fprintf(stderr, "Create CTcpPoll Error:%d\n", iRet);
  31.                 return E_FAIL;
  32.         }
  33.         DEBUG_LOG("CTcpPoll Create Succ: %p", CTcpPoll::Ins());

  34.         /* 初始化統(tǒng)計(jì)對(duì)象。 */
  35.         char pathWithPid[512] = {'\0'};
  36.         snprintf(pathWithPid, sizeof(pathWithPid)-1, "%s_%d", g_conf.m_stat._prefix, pid);
  37.         iRet = CProxyStat::Instance().Init(g_conf.m_stat._path, pathWithPid);
  38.         if( E_OK!=iRet ){
  39.                 fprintf(stderr, "Create CProxyStat Error:%d\n", iRet);
  40.                 return E_FAIL;               
  41.         }
  42.         DEBUG_LOG("CProxyStat Create Succ: %p", &(CProxyStat::Instance()));

  43.         return 0;
  44. }

  45. int MainThread()
  46. {
  47.         InitGlobalInstance();

  48.         time_t tNow = time(NULL);
  49.         while(true){
  50.                 _g_child_flag = 1;
  51.                 /* 處理連接任務(wù) */
  52.                 CPollerUnit::Ins()->ProcessAllEvents();
  53.                        
  54.                 /* 超時(shí)檢查*/
  55.                 CSession::Ins()->CheckTimeOut();

  56.                 /* 清理空閑的tcp連接。 */
  57.                 CTcpPoll::Ins()->CheckIdle(g_conf.m_session._idle, g_conf.m_session._timeInterval, g_conf.m_session._emptyRatio);

  58.                 /* 檢查是否到了統(tǒng)計(jì)間隔 */
  59.                 if( int(time(NULL) - tNow) < g_conf.m_stat._interval) continue;
  60.                 CProxyStat::Instance().ProcessStat();
  61.                 tNow = time(NULL);
  62.         }
  63.        
  64.         return -1;
  65. };


  66. int fork_process_group()
  67. {
  68.         //process group配置
  69.         int cpu_process_num = sysconf(_SC_NPROCESSORS_CONF);
  70.         int process_group_num        = g_conf.m_iProcessNum;       
  71.        
  72.         /* 不指定進(jìn)程個(gè)數(shù),或者指定進(jìn)程數(shù)比cpu個(gè)數(shù)還多,修改為cpu的個(gè)數(shù)。 */
  73.         if( 0 == process_group_num || process_group_num > cpu_process_num )
  74.                 process_group_num = cpu_process_num;

  75.         ERROR_LOG( "cpu num: %d, config process num: %d, real process num: %d", cpu_process_num, g_conf.m_iProcessNum, process_group_num);

  76.         int pid;
  77.         for(int i = 0; i < process_group_num ; i++)
  78.         {
  79.                 pid = fork();
  80.                 switch(pid)
  81.                 {
  82.                         case -1:
  83.                                 ERROR_LOG("fork error!");
  84.                                 return -1;

  85.                         case 0:
  86.                                 SetRunCpu( i );
  87.                                 MainThread();
  88.                                 return 0;

  89.                         default:
  90.                                 g_processcpu.insert(make_pair(pid, i));
  91.                 };
  92.         }

  93.         return 0;
  94. }


  95. int main(int argc,char** argv)
  96. {
  97.         if( argc <2 ){
  98.                 fprintf(stderr, "usage:%s etc\n", argv[0]);
  99.                 return -1;
  100.         }

  101.         /* 顯示系統(tǒng)說(shuō)明。 */
  102.         if( 0==strcasecmp(argv[1], "-v") ){
  103.                 PrintVersion();
  104.                 return 0;
  105.         }
  106.         PrintVersion();

  107.         /* 初始化,讀取配置文件。 */
  108.         int iRet = g_conf.Init(argv[1]);
  109.         if( E_OK != iRet ){
  110.                 fprintf(stderr, "Init Conf Error!:%d\n", iRet);
  111.                 return E_FAIL;
  112.         }

  113.         /* 初始化log */
  114.         log_init(g_conf.m_log._path, g_conf.m_log._level, g_conf.m_log._size, g_conf.m_log._prefix);

  115.         /* 設(shè)置信號(hào) */
  116.         SetUser1Handle();
  117.         /* 綁定cpu */
  118.         //if ( g_conf.m_iCpuBind>= 0 )        SetRunCpu(g_conf.m_iCpuBind);       


  119.         /* 監(jiān)聽(tīng)端口 */
  120.         if ( CreateClientSocket() < 0 )
  121.         {
  122.                 fprintf(stderr, "CreateClientSocket\n");
  123.                 return E_FAIL;
  124.         }
  125.         DEBUG_LOG("CreateClientSocket Succ!");

  126.         /* fork進(jìn)程,設(shè)置為守護(hù)進(jìn)程。 */
  127.         daemon_init();

  128.         fork_process_group();

  129. #ifndef DEBUG       
  130.         pid_t pid;
  131.         for(;;)
  132.         {
  133.                 pid = waitpid(-1,NULL,0);
  134.                 if ( pid <= 0 )
  135.                 {
  136.                         ERROR_LOG("waitpid error:%s\n", strerror(errno));
  137.                         sleep(1);
  138.                         continue;
  139.                 }
  140.                 fflush(NULL);
  141.                
  142.                 ERROR_LOG("WorkMain[%d] restart...................................\n", pid);
  143.                 usleep(100000);
  144.                
  145.                 int cpunum = g_processcpu.find(pid) == g_processcpu.end()?  0 : g_processcpu[pid];
  146.                 int newpid = fork();
  147.                 switch(newpid){
  148.                         case -1:
  149.                                 ERROR_LOG("fork error\n");
  150.                                 break;
  151.                         case 0:
  152.                                 SetRunCpu(cpunum);
  153.                                 MainThread();
  154.                                 break;
  155.                         default:
  156.                                 g_processcpu[newpid] = cpunum;
  157.                                 break;
  158.                 }
  159.         }
  160. #endif
  161.        
  162.         return 0;
  163. }

復(fù)制代碼

論壇徽章:
7
IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-27 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-06-09 06:20:00操作系統(tǒng)版塊每日發(fā)帖之星
日期:2016-06-12 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-06-12 06:20:00操作系統(tǒng)版塊每日發(fā)帖之星
日期:2016-06-13 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-06-17 06:20:002015-2016NBA季后賽紀(jì)念章
日期:2016-06-28 17:42:27
2 [報(bào)告]
發(fā)表于 2011-04-23 19:26 |只看該作者
CPollerUnit這個(gè)東西是C里面的不?我咋沒(méi)見(jiàn)過(guò)啊,還是你自定義的,請(qǐng)指教

論壇徽章:
0
3 [報(bào)告]
發(fā)表于 2011-04-23 19:32 |只看該作者
自定義的類,封裝epoll操作。

論壇徽章:
0
4 [報(bào)告]
發(fā)表于 2011-04-25 15:18 |只看該作者
cisco,linux,oracle授權(quán)培訓(xùn)中心,高端的IT培訓(xùn),中心03年成立,本著以客戶為中心的宗旨,有需要的朋友請(qǐng)聯(lián)系:朱老師:13777819351  QQ:365850824   博學(xué)教育
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP