2012-01-13 2 views
7

Come viene scritto il codice di chiamata del sistema di forcelle. Voglio sapere alcuni dettagli su come una funzione può restituire due valori diversi e quello a due processi diversi. In breve, vuoi sapere come viene implementata la chiamata di sistema fork?Implementazione forcella

+3

Puoi provare a guardare il codice sorgente del kernel Linux ... – fge

+1

Sei a tuo agio con l'idea che il sistema operativo può creare processi e puoi scegliere quali aree di memoria mappare allo spazio degli indirizzi di ogni processo? –

+0

quale punto mettere in dubbio? – Svisstack

risposta

9

Hai praticamente spiegato dicendo che si tratta di una chiamata di sistema. È compito del sistema operativo fare tutto ciò che funziona, e il sistema operativo può fare praticamente tutto ciò che vuole al di fuori del contesto del tuo programma o delle regole di qualunque lingua tu stia implementando. Ecco un semplice esempio di come potrebbe accada:

  1. programma chiama fork() chiamata di sistema
  2. kernel chiamata di sistema fork duplica il processo in esecuzione del programma di
  3. il kernel imposta il valore restituito per la chiamata di sistema per il programma originale e per il duplicato (PID il duplicato e 0, rispettivamente)
  4. Il kernel mette entrambi i processi in la coda schedulatore
  5. Ogni processo è pianificato, il kernel 'restituisce' ciascuno dei due programmi.
-1

In modo semplice per il processo di esempio, viene clonato in fork() funzione con Moving IP/EIP/RIP registro di saltare qualche istruzione in funzioni che possono apparire come:

return pid; 
return 0; 

primo processo eseguirà prima istruzione e funzione pop dallo stack, il secondo processo parte ma dalla seconda istruzione restituisce 0.

+0

Penso che sia solo il kernel che restituisce valori diversi dalla chiamata di sistema per ogni processo. – tangrs

+0

Entrambi fork di processo dallo stesso punto quando si chiama fork(). Non so cosa intendi con il processo "secondo" (genitore o figlio) ma è errato – iantonuk

2

C'è un commento nel booklet del codice sorgente Unix V6 per le università che è stato annotato da Ken Thomps e Dennis Ritchie stessi che descrivono come funziona il doppio ritorno. Il commento termina con la seguente frase:

Non ci si aspetta che lo capiscano.

+0

IIRC che si riferiva all'assembly utilizzato per quello, non all'idea di restituire due volte se stesso. – ninjalj

7

La risposta di Carl è stata grandiosa. Vorrei aggiungere che in molti sistemi operativi i valori di ritorno sono passati in uno dei registri. Nell'architettura x86 questo registro potrebbe essere eax, nell'architettura ARM questo registro potrebbe essere R0, ecc.

Ogni processo ha anche un blocco di controllo processo (PCB), che memorizza i valori dei registri nel momento in cui alcuni interrupt, syscall o si è verificata un'eccezione e il controllo è stato passato al sistema operativo. La volta successiva in cui il processo è pianificato, i valori dei registri vengono ripristinati dal PCB.

Ora, quando fork() accade, OS può fare:

child_process->PCB[return_value_register] = 0; 
parrent_process->PCB[return_value_register] = child_pid; 

Così, quando i processi vengono riprogrammate, ciascuno di essi vedono un valore di ritorno diverso.

Ad esempio, è possibile vedere xv6's implementation of fork. In questo caso, il processo principale è ancora in esecuzione, quindi restituisce il valore di ritorno del genitore usando la semplice dichiarazione di ritorno. Ma è imposta valore del registro EAX per processo figlio a 0, in modo che quando il processo figlio è in programma vede 0 come valore di ritorno:

// Clear %eax so that fork returns 0 in the child. 
np->tf->eax = 0; 

Nota che restituiscono 0 sarà anche compilare in qualcosa come "eax mov, 0".

Aggiornamento: Ho appena implementato fork() per un sistema operativo per hobby che sto facendo. Puoi vedere il codice sorgente here.