2015-07-22 11 views
5

Ecco un codice:variabili dopo forchetta

int i=0; 
pid_t pid; 

puts("Hello, World!"); 
puts(""); 

pid = fork(); 

if(pid) 

    i=42; 

printf("%p\n", &i); 
printf("%d\n", i); 
puts(""); 

E uscita

Hello, World! 

0x7fffc2490278 
42 

0x7fffc2490278 
0 

stampa Programma Ciao, mondo! una volta, quindi, il processo figlio non è stato avviato dall'inizio e non è stato ridefinito le variabili. Gli indirizzi delle variabili sono gli stessi. Quindi sono uguali. Ma cambio il valore di I nel processo genitore che viene eseguito per primo, non è cambiato per il processo figlio. Perché?

+0

Uh, non hai cambiato "i" fino a * dopo * la forcella(). Potresti vedere il display in qualsiasi ordine: genitore prima o genitore dopo figlio. Ma * solo * il genitore mostrerà "42"; il bambino sarà sempre "0". – paulsm4

+0

questa riga, dopo la chiamata al fork(): 'if (pid)' non è corretta. fork() restituisce -1 quando si verifica un errore (e si verificano occasionalmente). Quindi il codice agirà come se fosse un genitore di successo quando il fork() in realtà fallisce. Esistono diverse chiamate di funzioni di sistema in cui il codice di ritorno deve sempre essere controllato per assicurare che l'operazione abbia avuto esito positivo. fork() è una di quelle funzioni di sistema. La linea sarebbe molto meglio come: 'if (pid> 0)' Ancora meglio sarebbe anche controllare se pid <0 e gestire l'errore – user3629249

risposta

10

Gli indirizzi delle variabili sono uguali. Quindi sono uguali. Ma cambio il valore di I nel processo genitore che viene eseguito per primo, non è cambiato per il processo figlio. Perché?

Gli indirizzi sono nell'ambito di un processo. Sono indirizzi virtuali. L'indirizzo 0x7fffc2490278 nel processo principale e 0x7fffc2490278 nel processo figlio sono diversi indirizzi fisici.

+0

@thoron - non ti sei reso conto che gli indirizzi sono unici * per processo *? Che 0x10000 in un processo è un indirizzo fisico completamente diverso da 0x10000 in un altro processo? O che "l'indirizzo logico" 0x10000 può * cambiare * in un * diverso * indirizzo fisico * mentre il processo è in esecuzione *? Guarda qui per ulteriori dettagli: http://computer.howstuffworks.com/virtual-memory.htm – paulsm4

6

Quando si esegue fork(), verrà creato un intero processo, comprese le variabili. Quindi i nel genitore non è i del bambino. Hanno lo stesso indirizzo virtuale ma non lo stesso indirizzo fisico. La modifica è completamente indipendente.

3

Dal man page per forcella:

In caso di successo, il PID del processo figlio viene restituito nel genitore, e 0 viene restituito nel bambino. In caso di errore, -1 viene restituito nel genitore , non viene creato alcun processo figlio e errno viene impostato in modo appropriato.

Cioè, per il pid genitore viene impostato su un numero maggiore di 0 (o -1 se il fallimento si dovrebbe anche verificare).

if(pid) viene valutato come if(true)

ed eseguirà per il genitore. Il bambino, tuttavia, ottiene 0 assegnato a pid (è così che sa che è il bambino).

if(0) viene valutato come if(false)

e quindi il valore dei non cambia.

Tuttavia, a causa delle astrazioni processo vede memoria indirizzi virtuali (spazio di indirizzi virtuali che è esattamente copiato con fork). Solo il kernel può gestire gli indirizzi fisici e il processo comunica con il kernel per ottenere questa memoria (il processo dice semplicemente "inserisci questa variabile i a questo indirizzo: 0x7fffc2490278" e il kernel lo mapperà praticamente ovunque lo desideri). Per quanto ne sa il processo, è l'unico processo che richiede memoria ed è per questo che i loro indirizzi sono "uguali".

+1

se (-1) verrà eseguito. tutto è vero eccetto 0. ma questo è solo un codice di prova, mi aggrappo. : D Dovrebbe essere pid> 0. –

2

Le variabili vivono nello spazio degli indirizzi virtuali del processo. Lo spazio degli indirizzi di un processo è locale a quel processo. Il fatto che tu veda lo stesso indirizzo in due elaborati non significa che stai accedendo alla stessa variabile. Affatto.

I valori degli indirizzi hanno senso solo nel contesto del proprio processo. Non ha senso confrontare gli indirizzi degli spazi degli indirizzi di diversi processi.

La variabile i nel processo principale è completamente separata dalla variabile i nel processo figlio. Hai cambiato solo uno i (quello del genitore), che è esattamente ciò che osservi nell'output.