|
Appunti informatica |
|
Visite: 1549 | Gradito: | [ Picolo appunti ] |
Leggi anche appunti:La codifica delle informazioniLa codifica delle informazioni Nell'elaboratore tutte le informazioni Architettura RISCdArchitettura RISCd Il tipo fondamentale di RISCd è l'intero a 32 bit, corrispondente APPUNTI DI INFORMATICA TEORICA - Complessità computazionale, funzioni ricorsive, liste, alberiUNIVERSITA' DEGLI STUDI DI PISA CORSO DI INGEGNERIA INFORMATICA (NUOVO ORDINAMENTO) APPUNTI |
Primitiva Fork
Il meccanismo basilare per creare un processo è la primitiva Fork, chiamata dall'interno di un altro processo (al limite dallo Shell): un processo denominato padre crea in memoria un processo clone di sé stesso denominato figlio. Un processo figlio è quasi la copia esatta del processo padre giacchè eredita da esso il codice, i dati, lo stack, i descrittori di file aperti e la visibilità di ogni altra risorsa controllata dal padre; chiaramente essi risulteranno distinti per il PID, il PPID (ovvero il PID del processo padre) e per l'utilizzo delle risorse in run-time. In generale, in un sistema Non Multithreading, ereditare significa duplicare, per cui all'atto della creazione del nuovo processo il codice del padre viene duplicato per il figlio, un nuovo PCB indipendente viene allocato e viene creato un nuovo spazio di indirizzamento per fare sì che il figlio abbia copie indipendenti dei dati ereditati dal padre (una tecnica efficiente utilizzata da Unix, che è un SO Multitasking ma non Multithreading, è quella del copy on write, ovvero al processo figlio non sarà allocata memoria fisica fino al momento in cui uno dei due processi non effettuerà una scrittura sui dati condivisi: in pratica il figlio condividerà i segmenti di memoria del padre fin quando essi saranno di sola lettura per entrambi, altrimenti si procederà alla duplicazione effettiva). A titolo di esempio consideriamo il codice C seguente
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
main() else if (pid > 0) printf('Padre!');
//Se la fork() restituisce un valore minore di 0 significa che il processo figlio non è stato creato
//ad esempio per un eccessivo numero di processi attualmente attivi
else
La chiamata fork( ) è detta chiamata asincrona di procedura, differente da una classica chiamata di procedura perchè il processo chiamante non viene sospeso ma questo, insieme al processo chiamato, vengono eseguiti in due contesti differenti, come processi indipendenti eseguiti in parallelo: il processo figlio partirà nello stato New o direttamente nello stato Ready, e non appena sarà Running eseguirà la prima istruzione che segue la fork; per riconoscere dall'interno di ciascuno dei due processi di quale si tratti (del padre o del figlio) occorre valutare il PID restituito dalla primitiva fork.
Supponiamo che il processo in esecuzione contenga un codice del tipo
A: fork(X);
B:
X: "prima istruzione del processo invocato da FORK"
la chiamata A : fork(X) produce un processo figlio la cui prima istruzione utile sarà quella corrispondente alla label X, quindi coerentemente con quanto già detto finora, sullo stesso codice vengono percorsi concorrentemente due flussi di controllo distinti (graficamente da un nodo A parte una biforcazione verso due nodi successivi B e X). Un possibile algoritmo pascal-like della fork può essere
Procedure fork(id);
begin
if esiste_PCB_libero then
begin
<alloca descrittore libero al processo figlio>
<alloca spazi di memoria al processo figlio (inizializzati ai dati del padre)>
<inizializza il descrittore del figlio (id determina il PC)>
<poni il processo figlio in stato ready>
else
<poni il processo padre in attesa di un descrittore libero>
Context_Switch;
end;
end;
Appunti su: |
|