2009-10-14 8 views
8

次のコードスニペットは、すべてが同じリスニングソケットを共有する4つのプロセスを作成します。接続を受け入れる前または後にフォークしますか?

これを行う際に危険がありますか?従来の方法で、接続が受け入れられた後、常に1つのリスニングプロセスとフォークを用意する必要がありますか?

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); 
} 

(私は受け入れた後フォークするプログラムは、接続ごとにプロセスを行うことができますことを理解しています。私は、原糸と、さまざまな非同期のもので遊んでいたので、私はちょうどコアあたり1つのプロセスを持つ時​​に探しています)

答えて

10

いずれにしてもかまいません。

受諾後にフォークするのは、クライアント/接続ごとに1人の子供です。受け入れ前のフォーク(しかし、聞いた後)は一般にプレフォークとして知られています。子どものそれぞれは、受け入れを待ち、着信接続がそれを処理する子を取得します。これは、現代のUNIXが(私が思う)カーネルによって受け入れが行われる限り、安全です。もしそうでなければ、受け入れの周りにある種のIPC(ミューテックスなど)を入れなければなりません。事前分岐の利点は、接続ごとにフォークを費やす必要はなく、すでにプールがあることです。

+0

私は、TCPレイヤーでフードの背後にあるTCP接続(別名ツリー・ハンドル・シェイク)を受け入れることを実行するのは3つ目のカーネルの義務ですが。ここでIPCの種類は必要ないと確信していました。誰かがそれのどこにplatormを知っていますか? –

+6

Stevensによると、BSD由来のカーネルはいつもそれを行いました。いくつかの古いSysVシステムでは、ライブラリで受け入れを実装し、ロックが必要でした。それは、誰もが古い生産OSを実行している疑いがありますが、私はあなたが決して知らないと思います。 – Duck

+0

プリフォークを使用している場合、Linuxではsetsockopt(server_fd、REUSEPORT)は必要ありません。 –

関連する問題