2015-02-21 9 views
27

Ho letto nei libri e nelle risorse online che la chiamata di sistema fork() crea una copia del processo corrente ed entrambi i processi iniziano l'esecuzione dal punto dopo il fork() viene effettuata la chiamata di sistema. È corretto?Il comportamento della chiamata di sistema fork() su questo codice in questo codice

Se è corretto, perché il seguente codice stampa "Test Test"? Dovrebbe stampare "Test" solo una volta (secondo il processo genitore).

#include <sys/types.h> /* pid_t */ 
#include <sys/wait.h> /* waitpid */ 
#include <stdio.h>  /* printf, perror */ 
#include <stdlib.h> /* exit */ 
#include <unistd.h> /* _exit, fork */ 


int main(void) 
{ 
    int ctr =1; 
    int pc = 1; 
    printf("%s", "Test "); 
    pid_t pidmain = fork(); 
    return EXIT_SUCCESS; 
} 
+12

Aggiungere un "\ n" alla stringa "test". – wildplasser

+0

@wildplasser sorprendentemente dopo aver aggiunto \ n Ho ottenuto Test (Single time) non 2 volte. Ma perché? –

+16

Buffering di linea di stdout. Le copie fork() del tuo programma hanno entrambi un buffer semi-pieno su stdout, che viene svuotato all'uscita del programma. (entrambe le uscite). Per dimostrarlo, potresti anche aggiungere un sleep (1) appena prima del fork() – wildplasser

risposta

37

Quando si chiama fork() il sistema operativo crea una copia dei processi in corso tutta la memoria (in realtà non copiare la memoria in quanto può utilizzare la MMU per fare questo in modo efficace).

Poiché stdout è bufferato per impostazione predefinita, stamperà il messaggio solo una volta che un carattere di nuova riga è stato scritto o il flusso è stato svuotato. Quando si esegue il fork di un nuovo processo, anche il buffer di scrittura corrente (contenente "Test") verrà duplicato nel nuovo processo. Questo verrà quindi stampato una volta che il processo è terminato poiché chiude implicitamente (e svuota) lo stdout. Se si sostituisce printf("%s", "Test "); con printf("%s\n", "Test "); o si aggiunge una chiamata fflush(stdout); prima dello fork(), verrà visualizzato l'output previsto.

+6

o se la libreria C decide che sta iniziando a essere troppo nel buffer ... Sarebbe sbagliato dipendere dall'output rimanente nel buffer e da copiare durante la chiamata a forcella. –

18

Nel punto in cui si chiama fork, entrambi i processi hanno la stringa "Test" nei relativi buffer per l'output standard. Quando ciascun processo termina, entrambi scaricano questo testo nell'output (vedere exit per la spiegazione). Si potrebbe (come suggerito) aggiungere una nuova riga al buffer (e sarebbe successo uscire a causa del buffering - vedere setbuf per la spiegazione). Oppure puoi chiamare fflush (stdout) prima della forcella e ottenere esattamente quello che hai chiesto - la stringa "Test".

+0

Grazie per aver segnalato link utili. –