fork () si ramifica più del previsto?

Considera la seguente parte di codice:

#include  #include  #include  int main(void) { int i; for(i = 0; i < 2; i++) { fork(); printf("."); } return 0; } 

Questo programma emette 8 punti. Come può essere ansible? Non dovrebbero esserci invece 6 punti?

La fork() primitiva spesso distende l’immaginazione. Fino a quando non ne hai un’idea, dovresti tracciare su carta ciò che ciascuna operazione è e tenere conto del numero di processi. Non dimenticare che fork () crea una copia quasi perfetta del processo corrente. La differenza più significativa (per la maggior parte degli scopi) è che il valore di ritorno di fork() differisce tra genitore e figlio. (Poiché questo codice ignora il valore restituito, non fa differenza).

Quindi, all’inizio, c’è un processo. Ciò crea un secondo processo, entrambi i quali stampano un punto e un ciclo. Alla loro seconda iterazione, ognuno crea un’altra copia, quindi ci sono quattro processi che stampano un punto e poi escono. Quindi possiamo facilmente tenere conto di sei punti, come ti aspetti.

Tuttavia, ciò che fa veramente printf() è il buffer del suo output. Quindi il primo punto da quando c’erano solo due processi non appare quando scritto. Questi punti rimangono nel buffer, che è duplicato a fork (). Non è fino a quando il processo sta per uscire che appare il punto bufferizzato. Quattro processi di stampa di un punto buffer, più il nuovo dà 8 punti.

Se vuoi evitare questo comportamento, chiama fflush(stdout); dopo printf() .

Hai buffer non salvati nei flussi di output . stdout è bufferizzato in modo lineare e il buffer viene replicato insieme al resto del processo. Al termine del programma, il buffer non impegnato viene scritto due volte (una volta per ogni processo). Entrambi usano

 printf("a\n"); 

e

 printf("a "); fflush(stdout); 

non mostrare il problema

Nel tuo primo esempio, crei quattro processi che hanno ciascuno due punti nel buffer del stream di output. Quando ogni stream termina, scarica il buffer, generando otto punti.

quando i = 0

Process_1: testo bufferizzato = 1 punto

Process_2 (creato da Process_1): testo bufferizzato = 1 punto

quando i = 1

Process_3 (creato da Process_1): eredita 1 punto buffer da Process_1 e stampa 1 punto da solo. In totale, Process_3 stampa 2 punti.

Process_4 (creato da Process_2): eredita 1 punto buffer da Process_2 e stampa 1 punto da solo. In totale Process_4 stampa 2 punti.

Process_1: stampa 2 punti (un punto bufferizzato quando i = 0 e un altro punto quando i = 1)

Process_2: stampa 2 punti (One buffered dot quando i = 0 e un altro punto quando i = 1)

Uscita finale: 8 punti. 🙂