2009-10-14 28 views
8

El siguiente fragmento de código crea 4 procesos, todos compartiendo el mismo socket de escucha.¿Tenedor antes o después de aceptar conexiones?

¿Hay algún peligro al hacer esto? ¿Debería tener siempre un solo proceso de escucha y un tenedor después de que se acepten las conexiones, de la manera convencional?

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

(entiendo que se bifurcan después de aceptar permite que un programa para hacer un proceso por conexión. Estoy jugando con los proto-hilos y varias cosas asíncrono, así que sólo estoy mirando a tener un proceso por núcleo .)

Respuesta

10

Puede hacerlo de cualquier manera.

Como nota, el bifurcar después de aceptar es un hijo por cliente/conexión. Bifurcar antes de aceptar (pero después de escuchar) generalmente se conoce como preentreking. Cada uno de los niños espera en el aceptar y lo que sea que el niño reciba la conexión entrante lo procesa. Esto es seguro siempre que la aceptación sea realizada por el núcleo, lo que (creo) hace cualquier unix moderno. De lo contrario, debe colocar algún tipo de bloqueo IPC (mutex, etc.) alrededor del aceptar. La ventaja de prehornear es que no necesita pagar el gasto de un tenedor para cada conexión, ya tiene un grupo existente.

+0

Creo que es deber del kernel realizar una conexión tcp detrás del cofre (también conocido como tree tree handle shake) en la capa TCP. Estaba seguro de que no se necesitaba ningún tipo de IPC aquí. ¿Alguien en SO sabe un platerm dónde está? –

+6

Según Stevens, los kernels derivados de BSD siempre lo hicieron. Algunos sistemas SysV más antiguos implementados aceptan en una biblioteca y se requiere bloqueo. Es dudoso que alguien tenga un sistema operativo de producción tan antiguo, pero supongo que nunca se sabe. – Duck

+0

No necesitamos setsockopt (server_fd, REUSEPORT) en Linux si usamos pre-fork, ¿verdad? @Duck –

Cuestiones relacionadas