2011-12-13 30 views
19

Sé que puede ser cualquiera de estos. Pero siempre veo que el niño se ejecuta primero en mi terminal UNIX. Además, ¿por qué el padre y el hijo no se ejecutan en paralelo? Parecen estar ejecutándose en serie. ¿Esto es porque comparten el mismo terminal?¿Quién se ejecuta primero después de fork(): padre o hijo?

+1

posible duplicado de [ Puede el orden de ejecución de la horquilla() se determinará?] (http://stackoverflow.com/questions/6696959/can-the-order-of-execution-of-fork-be-determined) – Lekensteyn

Respuesta

17

En general, nada se puede decir sobre el orden relativo de su ejecución.

Ahora, consideremos su problema específico. Si:

  1. ambos procesos tienen una cantidad no trivial de tiempo para correr, y
  2. que está diciendo que uno ejecuta hasta el final antes de que las otras marcas ningún progreso, y
  3. existen sin usar Ciclo de CPU, y
  4. esto ocurre cada vez que ejecuta la aplicación.

Lo más probable es que esto indique que hay una sincronización (tal vez no intencionada) entre los dos procesos.

+1

+1.Depende del programador subyacente decidir cómo programar los diversos hilos. – Vicky

+1

@aix: Ambos progresan. Estoy haciendo una impresión simple tanto en padres como en hijos. Nunca veo sus printfs intercalados. Es siempre printf infantil (~ 100 agrupados juntos) ... printfs padres (agrupados juntos) ... printfs infantiles .. – Bruce

+0

@Bruce: ¿Estás seguro de que esto no se debe a la salida de almacenamiento en búfer (estás escribiendo en la terminal o a un archivo/tubería)? Además, 'top' debería darle una idea de si los dos procesos se están ejecutando" en paralelo ". – NPE

1

No hay realmente una ejecutándose antes que la otra. Es simplemente que el padre va a fork() y luego wait() para que el niño lo complete. Incluso puede bifurcarse varias veces si utiliza una serie de comandos canalizados, por ejemplo.

6

En realidad, ese es el comportamiento previsto, incluso si no está funcionando como debería, lo que significa que el padre puede ejecutar antes de que el niño y el niño puedan ejecutarse antes que el padre.

El objetivo es ejecutar primero el proceso secundario.

En resumen, la lógica detrás de esto es que si el hijo se ejecuta primero, la sobrecarga de copy on write (COW) se elimina si el hijo llama al exec ya que el padre no tiene ninguna posibilidad de escribir en la dirección espacio.

3

Si está llamando a vfork, casi todas las implementaciones definen que el hijo se ejecutará primero y luego se ejecutará el padre. (Hasta las llamadas secundarias ejecutivas) .Así verá la ejecución en serie en el caso de vfork independientemente de schedular.Sin embargo, cuando fork se llama simplemente dos nuevos procesos creados. Pueden ejecutarse de forma independiente (como cualquier otro proceso). El proceso que se ejecuta primero dependerá en gran medida del algoritmo de programación. Además del algoritmo de programación, el número de procesos que se ejecutan en ese momento también determinará la naturaleza de la salida. Además, si está utilizando las funciones de E/S estándar de la biblioteca, generan datos en ráfagas (probablemente no la palabra correcta). Eso también determinará en cierta medida quién escribe primero. Aquí es un ejemplo de código (Eso no tiene mucho sentido prácticamente pero sigue siendo un buen ejemplo de que padre e hijo en verdad funcionan en sincronismo

#include<stdio.h> 
    #include<string.h> 
    static void charAtTime(char buff[]) 
{ 
char *p=buff; 
while(*p) { 
putc(*p,stdout); 
(p++); 
} 

} 
    int main() 
{ 
setbuf(stdout,NULL); //set output stream to be unbuffered.Now each process will try to throw chars as soon as they are ready 
int pid; 
char buff[1000]; 
if((pid=fork())<0) //First fork 
    { 
    fprintf(stderr,"Fork error\n"); 
    } 
else if(pid==0) 
    { 
    strcpy(buff,"i am the child.I love beyblade.I love anime.I love pokemon\n"); 
    charAtTime(buff);  
    } 
    else { 
    int pid2=fork(); //secnd fork 
    if(pid2==0){ 
    strcpy(buff,"I am the younger child\n"); 
     charAtTime(buff); 
     } 
    else { 
int pid3; 
pid3=fork(); //third fork 
if(pid3==0) 
    { 
    strcpy(buff,"I am from the 2nd generation\n"); 
    charAtTime(buff); 
    } 
    else { 
    strcpy(buff,"Our family tree is bit confusing\n"); 
    charAtTime(buff); 
    } 
     } 

    strcpy(buff,"I am the big daddy of them.I have the right before them\n"); 
    } 

    return 0; 
    } 

Para mi sistema la siguiente salida se

i am thOeI u ra cmfha mtihley yoIturne geea rmi cshf irblodimt 
    thceo i2nnlfdd .uIg elnseoivrnea gb 
    teiyobnl 
    ade.I love anime.I love pokemon 

Sin embargo, si reduce el número de horquillas a dos (solo dos procesos compiten), la salida es menos fea. Su padre se ejecuta primero. (Probablemente porque su proceso actual se ejecuta cuando se crea el otro proceso)

Cuestiones relacionadas