2012-06-06 15 views
17

Estoy empezando a aprender algo de C y mientras estudio la horquilla, las funciones de espera obtuve una salida inesperada. Al menos para mi.¿Cómo usar Fork() para crear solo 2 procesos secundarios?

¿Hay alguna manera de crear solo 2 procesos hijos del padre?

Aquí mi código:

#include <sys/types.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <sys/wait.h> 

int main() 
{ 
    /* Create the pipe */ 
    int fd [2]; 
    pipe(fd); 

    pid_t pid; 
    pid_t pidb; 


    pid = fork(); 
    pidb = fork(); 

    if (pid < 0) 
    { 
     printf ("Fork Failed\n"); 
     return -1; 
    } 
    else if (pid == 0) 
    { 
     //printf("I'm the child\n"); 
    } 
    else 
    { 
     //printf("I'm the parent\n"); 
    } 

    printf("I'm pid %d\n",getpid()); 

    return 0; 
} 

y aquí está mi producción:

I'm pid 6763 
I'm pid 6765 
I'm pid 6764 
I'm pid 6766 

Por favor, ignore la parte de tubo, no he llegado tan lejos. Solo intento crear solo 2 procesos secundarios, por lo que espero que 3 "I'm pid ..." produzca solo 1 para el padre, que haré esperar y 2 procesos secundarios que se comunicarán a través de un conducto.

Avísame si ves dónde está mi error.

+1

'tenedor (2)' es a la vez muy simple y una de las llamadas más incomprendidos en la API de Unix. Solo mira la barra lateral "Relacionada". ¿Hay alguna razón particular por la que desee comunicación entre dos niños y no entre el padre y el niño? – dmckee

+0

Para la llamada fork() ¿por qué está buscando pid == 0? ¿Cómo sé cuál es el padre y cuál es el niño? – TwilightSparkleTheGeek

+1

@TwilightSparkleTheGeek 'man fork' states: VALOR DEVUELTO En caso de éxito, el PID del proceso secundario se devuelve en el elemento primario y 0 se devuelve en el elemento secundario. En caso de error, -1 se devuelve en el elemento principal, , no se crea ningún proceso hijo y errno se configura de manera apropiada. – mimoralea

Respuesta

30
pid = fork(); #1 
pidb = fork(); #2 

Vamos a suponer la identificación del proceso padre es de 100, el primer tenedor crea otro proceso 101. Ahora, tanto & 100 101 continúan después de la ejecución # 1, para que ejecuten segundo tenedor. pid 100 llega al # 2 creando otro proceso 102. pid 101 alcanza el # 2 creando otro proceso 103. Así que terminamos con 4 procesos.

Lo que debes hacer es algo como esto.

if(fork()) # parent 
    if(fork()) #parent 
    else # child2 
else #child1 
+3

Eso definitivamente funciona. Sin embargo, recomendaría usar una instrucción switch en su lugar. La función de horquilla podría devolver un -1 y podemos manejar este error con el caso -1 dentro de una declaración de cambio. – sj755

+0

Pensé que el padre estaba después de la declaración else. ¿Por qué está el padre en la declaración if? Estoy confundido. – TwilightSparkleTheGeek

+1

Porque el tenedor devuelve 0 en el elemento secundario, no en el elemento primario. En el padre, devuelve el PID del proceso secundario que acaba de crear, que es más útil. – mimoralea

3

Cuando el padre ejecuta una instrucción de bifurcación, se crea un proceso secundario como era de esperar. Se podría decir que el proceso hijo también ejecuta el enunciado fork pero devuelve un 0, pero el padre devuelve el pid. Todo el código después de la instrucción de horquilla es ejecutado por ambos, el padre y el hijo.

En su caso, lo que sucedía era que la primera instrucción fork creaba un proceso hijo. Entonces, actualmente hay un padre, P1 y un hijo, C1.

Ahora tanto P1 como C1 encuentran la segunda declaración de la horquilla. El padre crea otro hijo (c2) como era de esperar, pero incluso el hijo, c1 crea un proceso hijo (c3). Entonces, en efecto, tiene P1, C1, C2 y C3, por lo que tiene 4 resultados de declaración de impresión.

Una buena forma de pensar sobre esto es usar árboles, donde cada nodo representa un proceso y el nodo raíz es el padre superior.

13

Después de crear el proceso, debe verificar el valor de retorno. si no lo hace, el seconde fork() será ejecutado tanto por el proceso principal como por el secundario, por lo que tiene cuatro procesos.

si desea crear 2 procesos secundarios, sólo:

if (pid = fork()) { 
    if (pid = fork()) { 
     ; 
    } 
} 

Puede crear n procesos secundarios como este:

for (i = 0; i < n; ++i) { 
    pid = fork(); 
    if (pid) { 
     continue; 
    } else if (pid == 0) { 
     break; 
    } else { 
     printf("fork error\n"); 
     exit(1); 
    } 
} 
0

se puede comprobar el valor que si (pid < 0) creación del proceso incorrecta esto indica si la creación del proceso secundario no tuvo éxito. fork devuelve la identificación del proceso del proceso hijo si getpid() se utiliza desde el proceso principal ss ..

0

Puede crear un proceso hijo dentro de un proceso secundario. De esta forma, puede tener 2 copias del proceso principal original.

int main (void) { 
    pid_t pid, pid2; 
    int status; 

    pid = fork(); 

    if (pid == 0) { //child process 
     pid2 = fork(); 
     int status2; 

     if (pid2 == 0) { //child of child process 
      printf("friends!\n"); 
     } 
     else { 
      printf("my "); 
      fflush(stdout); 
      wait(&status2); 
     } 
    } 
    else { //parent process 
     printf("Hello "); 
     fflush(stdout); 
     wait(&status); 
    } 

    return 0; 
} 

Esto imprime los siguientes:

Hello my friends! 
Cuestiones relacionadas