青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

小明思考

高性能服務器端計算
posts - 70, comments - 428, trackbacks - 0, articles - 0
  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

多進程服務端實現-共享socket

Posted on 2008-03-10 14:09 小明 閱讀(11252) 評論(3)  編輯 收藏 引用 所屬分類: Win32Network/ACE


眾所周知,使用多進程的服務端模型有利于程序的健壯性。傳統的做法是主進程負責收發數據,然后傳給子進程來處理。這種做法的缺陷是需要大量的父子進程IPC,對效率來說是一種損失。

這里,我提出另外一種比較獨特的做法,就是多個進程share socket,每次進程都可以accept,然后來自己處理。

幾個關鍵點:
1) CreateProcess使用InheritHandle標記來share socket handle
2) 通過command line直接向子進程來傳遞父socket的值
3)使用Global Mutext來實現子進程互斥的accept

可以改進的地方
1) 使用動態進程池來程序具有更大的伸縮性
2)監控子進程的狀態,處理僵死進程

下面是一個echo server 的例子來展示這項技術, FYI

父進程(SSParent.cpp)

#include <stdio.h>
#include 
<winsock2.h>
#include 
<windows.h>
#include 
<process.h>

#define MUTEX_NAME "sschild"

int main(int argc, char* argv[])
{
    { 
//init
        WORD wVersionRequested;
        WSADATA wsaData;
        wVersionRequested 
= MAKEWORD( 22 );
        WSAStartup( wVersionRequested, 
&wsaData );
    }

    SOCKET s 
= socket(AF_INET,SOCK_STREAM,0);
    
if(s==INVALID_SOCKET)
    {
        printf(
"create socket failed!\n");
        
return -1;
    }

    { 
//bind&listen
        sockaddr_in sa;
        sa.sin_family 
= AF_INET;
        sa.sin_port 
= htons( 1500 );
        sa.sin_addr.s_addr 
= 0 ; 
        
int rc = bind(s,(sockaddr *)&sa,sizeof(sa));
        
if(rc == SOCKET_ERROR)
        {
            printf(
"bind failed:%d\n",::WSAGetLastError());
            
return -1;
        }
        listen(s,SOMAXCONN);
    }

    HANDLE hSocketMutex;
    { 
//create mutex
        hSocketMutex = ::CreateMutex(NULL,FALSE,MUTEX_NAME);
        
if(hSocketMutex==NULL)
        {
            printf(
"fail CreateMutex:%d\n",::GetLastError());
            
return -1;
        }
    }

    
const int CHILD_NUMBER = 5;
    HANDLE hProcess[CHILD_NUMBER];
    { 
//create child process
       STARTUPINFO si = { sizeof(si) };
       PROCESS_INFORMATION piProcess[CHILD_NUMBER];
       
char pCmdLine[256];
       sprintf(pCmdLine,
"SSChild %d",s);
       
for(int i=0;i<CHILD_NUMBER;++i)
       {
           
if(!CreateProcess(NULL,pCmdLine,NULL,NULL,TRUE,0, NULL, NULL, &si, &piProcess[i]))
           {
               printf(
"fail CreateProcess:%d\n",::GetLastError());
               
return -1;
           }
           hProcess[i] 
= piProcess[i].hProcess;
           CloseHandle(piProcess[i].hThread);
       }
    }

    ::WaitForMultipleObjects(CHILD_NUMBER,hProcess,TRUE,INFINITE);

    {
//close all child handle
       for(int i=0;i<CHILD_NUMBER;++i)
       {
           CloseHandle(hProcess[i]);
       }
    }

    
//clean
    CloseHandle(hSocketMutex);
    closesocket(s);
    WSACleanup( );
    
return 0;
}

 

子進程(SSChild.cpp)

#include <stdio.h>
#include 
<winsock2.h>
#include 
<windows.h>
#include 
<process.h>

#define MUTEX_NAME "sschild"

int main(int argc, char* argv[])
{
    printf(
"sschild startup!\n");

    { 
//init
        WORD wVersionRequested;
        WSADATA wsaData;
        wVersionRequested 
= MAKEWORD( 22 );
        WSAStartup( wVersionRequested, 
&wsaData );
    }

    DWORD pid 
= ::GetCurrentProcessId();

    HANDLE hSocketMutex;
    { 
//open mutex
        hSocketMutex = ::OpenMutex(MUTEX_ALL_ACCESS,FALSE,MUTEX_NAME);
        
if(hSocketMutex==NULL)
        {
            printf(
"fail OpenMutex:%d\n",::GetLastError());
            
return -1;
        }
    }

    SOCKET s;
    {  
//get socket handle from cmdline
        if(argc<=1)
        {
            printf(
"usage: sschild socket_handle\n");
            
return -1;
        }
        s 
= (SOCKET) atoi(argv[1]);
    }

    
while(1)
    {
        WaitForSingleObject(hSocketMutex,INFINITE);
        sockaddr_in sa;
        
int add_len = sizeof(sa);
        SOCKET c 
= accept(s,(sockaddr*)&sa,&add_len);
        ReleaseMutex(hSocketMutex);
        
if(c!=INVALID_SOCKET)
        {
            printf(
"[%d],client:%s port:%d connected!\n",pid,inet_ntoa(sa.sin_addr),sa.sin_port);
            
while(1)
            {
                
char buffer[256]={0};
                
int rc= recv(c,buffer,255,0);
                
if(rc>0)
                {
                    printf(
"[%d]recv msg:%s\n",pid,buffer);
                    send(c,buffer,strlen(buffer)
+1,0);
                }
                
else if(rc == SOCKET_ERROR)
                {
                    printf(
"[%d]recv msg failed:%d\n",pid,::WSAGetLastError());
                    closesocket(c);
                    
break;
                }
                
else
                {
                    printf(
"[%d]connection close\n",pid);
                    closesocket(c);
                    
break;
                }
            }
        }
        
else
        {
            printf(
"[%d]fail accept:%d\n",pid,::WSAGetLastError());
        }
    }

    CloseHandle(hSocketMutex);
    
return 0;
}

Feedback

# re: 多進程服務端實現-共享socket[未登錄]  回復  更多評論   

2008-03-10 14:42 by cppexplore
“這里,我提出另外一種比較獨特的做法,就是......”
呵呵,兄弟啊,我畢業答辯的時候,老師就反復的批評我們,“我提出.......”,“我發明......”之類的東西。
文中就是《unix網絡編程》中的預派生進程阻塞在accept的方式嘛。
并且書中說明這種問題有驚群問題,可以前面加文件鎖或者線程鎖互斥,你文中加的是互斥鎖。現在的linux從2.2.9版本起就不存在驚群問題而不需要加鎖了,更好的是2.6內核的線程庫中線程鎖不陷入互斥狀態的話就不會陷入內核態了,加不加性能一樣。而win就沒有這么好的線程鎖。
多進程方式編程簡單,程序健壯性相對比較好,但是切換開銷比較大。現在的更傾向于預派生線程的方式。
另可以,起多個多線程的程序,bind不同port,前端部署lvs提供均衡負載一樣可以達到更好的多進程效果。

# re: 多進程服務端實現-共享socket  回復  更多評論   

2008-07-06 02:12 by 放屁啊狗
windows的socket只能說是個小玩藝兒,跟unix下的socket簡直無法比擬,可見windows只能做desktop系統

# re: 多進程服務端實現-共享socket[未登錄]  回復  更多評論   

2009-05-03 16:43 by sun
hProcess[i] = piProcess[i].hProcess;
piProcess[i].hProcess狀態改變,hProcess[i]狀態也改變?
仍沒弄明白
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产精品久久久久久妇女6080| 男人的天堂亚洲在线| 美女国产一区| 亚洲一区中文| 亚洲日本va午夜在线影院| 亚洲欧美国产毛片在线| 亚洲国产精品一区二区第四页av| 欧美乱大交xxxxx| 久久国产精品99久久久久久老狼 | 久久青青草原一区二区| 久久久免费av| 欧美乱人伦中文字幕在线| 好吊一区二区三区| 在线看国产日韩| 亚洲欧洲另类| 亚洲私拍自拍| 卡通动漫国产精品| 亚洲精品久久久久久久久久久久| 亚洲欧洲偷拍精品| 亚洲欧美日韩精品久久奇米色影视| 欧美一级片一区| 能在线观看的日韩av| 欧美三级乱人伦电影| 国产欧美日韩综合精品二区| 在线看片欧美| 午夜精品久久久久久久久久久久| 久久久久久久精| 亚洲国产另类精品专区| 亚洲欧美伊人| 欧美人成网站| 在线电影国产精品| 中国女人久久久| 乱人伦精品视频在线观看| 亚洲伦理在线免费看| 欧美综合国产| 国产精品视频观看| 99国产精品久久久久久久成人热| 欧美一区二区三区四区在线| 亚洲国产精品女人久久久| 欧美一级网站| 国产精品a久久久久久| 亚洲经典在线| 美女主播视频一区| 亚洲欧美国产高清va在线播| 欧美精品三级| 亚洲电影视频在线| 久久久久久伊人| 中文网丁香综合网| 欧美日韩国产精品成人| 悠悠资源网亚洲青| 久久精品国产视频| 中日韩男男gay无套| 欧美顶级少妇做爰| 亚洲国产精品精华液2区45| 久久久久久久综合色一本| 亚洲欧美国产精品va在线观看| 欧美日韩国产亚洲一区| 亚洲精品一区二区三区婷婷月| 免费在线看成人av| 久久久久久久久久久久久9999| 国产精品一区视频| 欧美怡红院视频一区二区三区| 亚洲视频一起| 国产精品欧美一区喷水| 亚洲欧美在线另类| 亚洲欧美日韩直播| 国产亚洲综合精品| 麻豆freexxxx性91精品| 久久久久久久久久看片| 宅男噜噜噜66一区二区| 欧美国产日韩二区| 欧美在线播放| 激情综合色综合久久综合| 久久综合九九| 午夜在线电影亚洲一区| 亚洲资源在线观看| 国模精品娜娜一二三区| 久久综合图片| 欧美成人精品一区| 亚洲午夜精品福利| 午夜视频在线观看一区| 一区二区亚洲欧洲国产日韩| 欧美波霸影院| 欧美视频日韩视频在线观看| 亚洲综合999| 久久精品导航| 亚洲伦伦在线| 亚洲亚洲精品三区日韩精品在线视频| 国产精品一区亚洲| 欧美电影在线播放| 欧美日韩日本国产亚洲在线| 亚洲一区二区三区免费观看| 欧美一区二区在线免费观看| 亚洲国产日韩一区二区| 日韩一级免费| 激情自拍一区| 亚洲蜜桃精久久久久久久 | 国产精品普通话对白| 久久精品女人的天堂av| 欧美理论电影在线观看| 久久久久久噜噜噜久久久精品| 欧美极品一区| 麻豆成人av| 国产精品久久久久毛片软件| 老牛国产精品一区的观看方式| 欧美日韩免费观看中文| 美女久久一区| 国产精品日韩在线一区| 亚洲国产成人在线播放| 国产欧美日韩另类一区| 亚洲美女视频在线观看| 亚洲二区在线视频| 亚洲欧美日韩综合国产aⅴ| 日韩视频在线观看国产| 久久久777| 久久精品国产久精国产一老狼 | 亚洲国内精品在线| 国产丝袜一区二区三区| 亚洲美女在线国产| 最新国产乱人伦偷精品免费网站 | 亚洲人体大胆视频| 久久精品国产亚洲一区二区| 亚洲女同性videos| 欧美日韩视频在线| 亚洲区一区二区三区| 亚洲国产精品99久久久久久久久| 午夜视频久久久久久| 亚洲黄一区二区三区| 欧美激情视频一区二区三区在线播放| 亚洲免费中文| 欧美日本在线看| 欧美大胆成人| 亚洲高清免费视频| 久久综合综合久久综合| 美女视频黄免费的久久| 黄色精品在线看| 久久久久久久欧美精品| 久久人人97超碰国产公开结果| 国产日韩亚洲| 久久精品色图| 美女亚洲精品| 91久久精品一区二区三区| 蜜臀av国产精品久久久久| 亚洲成在人线av| 亚洲乱码久久| 欧美日韩情趣电影| 亚洲一区国产| 久久久99久久精品女同性| 国产综合激情| 另类激情亚洲| 亚洲欧洲视频| 亚洲自拍电影| 国产一区二区三区在线免费观看| 久久黄色网页| 亚洲黄色一区二区三区| 在线视频欧美日韩| 国产日产精品一区二区三区四区的观看方式| 国产精品99久久久久久久女警| 亚洲欧美视频在线| 狠狠色狠狠色综合日日五| 免费日韩av片| 亚洲视频免费在线观看| 久久久久亚洲综合| 亚洲狼人精品一区二区三区| 欧美午夜电影在线| 久久久999国产| 亚洲人成在线播放网站岛国| 亚洲欧美视频一区二区三区| 精品91免费| 欧美日韩美女在线观看| 午夜欧美精品久久久久久久| 欧美黄色小视频| 亚洲欧美久久| 亚洲国产精品一区| 国产精品日韩一区二区| 蜜桃久久av| 亚洲欧美综合精品久久成人| 欧美成人免费大片| 亚洲欧美另类中文字幕| 亚洲国产美女| 国产毛片精品视频| 欧美国产日本| 欧美在线视频一区二区三区| 91久久精品美女高潮| 久久久久99| 亚洲欧美日韩爽爽影院| 亚洲欧洲精品一区二区三区| 国产美女高潮久久白浆| 欧美激情在线免费观看| 久久精品亚洲乱码伦伦中文| 夜夜狂射影院欧美极品| 欧美成人自拍视频| 久久国产主播| 亚洲综合欧美日韩| 亚洲美女毛片| 亚洲国产91精品在线观看| 国产视频亚洲| 国产精品视频久久一区| 欧美日韩亚洲一区二区三区| 免费成人小视频|