2009-10-14 84 views
8

以下代碼片段創建4個進程,全部共享相同的偵聽套接字。在接受連接之前或之後分叉?

這樣做有沒有危險?在傳統方式下,我是否應該在接受連接後始終有一個監聽流程和分支?

for (p = 0; p < 3; p++) { 
    pid = fork(); 
    if (pid == 0) break; 
} 
while (1) { 
    unsigned int clientlen = sizeof(echoclient); 
    /* Wait for client connection */ 
    if ((clientsock = 
     accept(serversock, (struct sockaddr *) &echoclient, 
       &clientlen)) < 0) { 
    die("Failed to accept client connection"); 
    } 
    fprintf(stdout, "Process No. %d - Client connected: %s\n", 
        p, 
        inet_ntoa(echoclient.sin_addr)); 
    handle_client(clientsock); 
} 

(我的理解,接受後分叉允許程序,使每個連接的過程。我與原線程和各種異步的東西玩耍,所以我只是在尋找具有核心每一個進程)

回答

10

你可以這樣做。

正如你所看到的,接受後的分叉是每個客戶端/連接的一個孩子。接受之前分岔(但聽後)通常稱爲預分岔。每個孩子都會等待接受,並且無論哪個孩子都會接受傳入的連接。這是安全的,只要接受是由內核完成的(我認爲)任何現代的unix都可以。如果不是這樣,你必須在接受處添加某種IPC(互斥鎖等)。預分叉的好處是你不需要爲每個連接花費一個分支,你已經擁有一個現有的分支。

+0

我雖然是內核職責,執行TCP層背後的引擎蓋(又名樹方式柄搖)接受tcp連接。我確定這裏不需要IPC。 SO上的某人是否知道它在哪裏? – 2009-10-14 21:54:06

+6

據史蒂文斯說,BSD派生的內核總是這樣做。一些較舊的SysV系統在庫中實現接受並且需要鎖定。可疑的是,任何人都在運行一箇舊的生產操作系統,但我想你永遠不知道。 – Duck 2009-10-14 22:36:18

+0

如果我們使用pre-fork,我們不需要Linux上的setsockopt(server_fd,REUSEPORT),對吧?@Duck – 2017-02-28 13:55:33

相關問題