2011-05-15 12 views
6

Estoy tratando el siguiente código C:¿Necesita saber cómo funciona el tenedor?

int main() 
{ 
    printf("text1\n"); 
    fork(); 
    printf("text2\n"); 
    return 0; 
} 

que estaba esperando para obtener la salida donde consigo dos "texto1" y dos "texto2", como:

text1 
text1 
text2 
text2 

Pero, soy , en cambio, obteniendo:

text1 
text2 
text2 

solo uno "text1" ??? Ok, si el proceso hijo ejecuta desde el tenedor(), entonces ¿Por qué recibo dos "texto1" para el siguiente:

int main() 
{ 
    printf("text1"); 
    fork(); 
    printf("text2\n"); 
    return 0; 
} 

la salida ahora es:

text1text2 
text1text2 

Si el proceso hijo se inicia después de el tenedor, la salida debe ser:

text1 
text2 
text2 
+1

¿Por qué esperarías dos copias de "text1"? Solo hay * un * proceso hasta que toques el 'tenedor'. – dmckee

+0

hombre tenedor? (..........) –

+0

@ user749391: El código funciona como se esperaba. Las preguntas como la suya no se pueden responder de manera significativa hasta que realmente explique * por qué * espera ver dos "texto1". – AnT

Respuesta

23

crea un nuevo proceso al copiar todo en el proceso actual en el nuevo proceso. Eso típicamente incluye todo en la memoria y los valores actuales de los registros de la CPU con algunos ajustes menores. Entonces, en efecto, el nuevo proceso también obtiene una copia del puntero de instrucción del proceso, por lo que se reanuda en el mismo punto donde continuaría el proceso original (la instrucción que sigue al fork()).


Para hacer frente a su actualización, printf() es amortiguada. Normalmente, el búfer se vacía cuando encuentra un carácter de nueva línea al final, '\n'. Sin embargo, como ha omitido esto, el contenido del búfer permanece y no se vacía. Al final, ambos procesos (el original y el secundario) tendrán el buffer de salida con "text1" en él. Cuando eventualmente se enrojezca, verá esto en ambos procesos.

En la práctica, siempre debe lavar los archivos y todos los búferes (que incluyen stdout) antes de bifurcar para asegurarse de que esto no ocurra.

printf("text1"); 
fflush(stdout); 
fork(); 

La salida debería tener este aspecto (en algún orden):

 
text1text2 
text2 
+0

Pero ¿por qué obtengo dos "text1" para lo siguiente: int main() { printf ("text1"); tenedor(); printf ("texto2 \ n"); return 0; } la salida actual es: text1text2 text1text2 Si el proceso hijo se inicia después de que el tenedor, la salida debe ser: texto1 texto2 texto2 – mandavi

+0

@adi: Actualización. –

+0

mucho mucho ... !! – mandavi

2

es porque fork proceso ed comienza después fork, no desde un principio. exec inicia el proceso desde el punto de entrada e imprimirá lo que espera.

+0

Todavía no puedo obtenerlo, porque cuando elimino "\ n" de la primera impresión(), recibo "texto1" dos veces, es decir, int main() { printf ("text1 "); tenedor(); printf ("texto2 \ n"); return 0; } la salida es: text1text2 text1text2 – mandavi

+3

Creo que en ese caso los procesos originales y bifurcados heredan la salida almacenada en búfer con "text1" ya que el final de línea no ha causado que el búfer se descargue. Asumiría que si hicieras un color en el stdout antes del tenedor verías lo que esperas ver. – Joe

6

fork clona el proceso actual. El nuevo proceso se "iniciará" en la llamada fork, no al comienzo de main como parece esperar. Por lo tanto, cuando imprime la primera vez hay 1 proceso, entonces cuando bifurca hay dos.

Dado que está fork después de imprimir "text1", solo se imprime una vez.

En el segundo ejemplo, la salida duplicada se debe al almacenamiento en búfer de salida - printf en realidad no muestra nada en la pantalla hasta que se vacía o llega a una nueva línea ('\n').

En consecuencia, la primera llamada a printf realidad acabo de escribir datos en una memoria intermedia en algún lugar, los datos se copian en el segundo proceso de espacio de direcciones, y luego la segunda llamada a printf habría vaciado del buffer, con "text1" tanto buffers.

1

El proceso hijo se iniciará desde la posición del tenedor(), por lo que está recibiendo la salida correcta.

+0

como dijiste, el proceso hijo comenzará desde fork(), debería obtener text1text2 text2, en el segundo caso – mandavi

7

El proceso bifurcado obtiene una copia de la memoria variable, y en el momento de la bifurcación, el búfer de salida aún no se ha lavado. No se ha escrito ningún resultado en la consola cuando se realiza la horquilla, solo se almacena en el búfer. Por lo tanto, ambos procesos continúan con el texto1 que ya está en el búfer y, por lo tanto, ambos lo imprimen.

+2

@adi, para obtener el resultado esperado debes poner 'fflush (stdout)' después de la primera printf –

+0

gracias a mucho....!! – mandavi

0

desde man 2 fork: fork devuelve 0 en el proceso secundario.

value = fork(); 
if(value == -1) { 
    printf("fork failed\n"); 
    exit(1); 
} 
if(value) { 
    printf("test1\n"); 
} else { 
    printf("test2\n" }; 
} 
1

Problem 1 : the output as 
     text1 
     text2 
     text2

Esto se debe a que tenedor() crear una copia exacta (niño) de proceso padre y ambos procesos comienzan su ejecución inmediatamente después de la llamada al sistema tenedor().

Problem 2 : the output as 
     text1text2 
     text1text2

Esto es todo sobre el almacenamiento en búfer. Consulte este enlace y conozca los conceptos básicos de fork(). http://www.csl.mtu.edu/cs4411.ck/www/NOTES/process/fork/create.html