Chiamate di sistema

Fork System Call Linux

Fork System Call Linux

Chiamata di sistema fork

La chiamata di sistema fork viene utilizzata per creare un nuovo processo. Il processo appena creato è il processo figlio. Il processo che chiama fork e crea un nuovo processo è il processo genitore. I processi figlio e padre vengono eseguiti contemporaneamente.

Ma i processi figlio e genitore risiedono su spazi di memoria differenti. Questi spazi di memoria hanno lo stesso contenuto e qualunque operazione venga eseguita da un processo non influenzerà l'altro processo.

Quando viene creato il processo figlio; ora entrambi i processi avranno lo stesso Program Counter (PC), quindi entrambi questi processi punteranno alla stessa istruzione successiva. I file aperti dal processo padre saranno gli stessi per il processo figlio.

Il processo figlio è esattamente lo stesso del suo genitore ma c'è una differenza negli ID dei processi:

  1. L'ID di processo del processo figlio è un ID di processo univoco che è diverso dagli ID di tutti gli altri processi esistenti.
  2. L'ID processo genitore sarà lo stesso dell'ID processo del genitore del figlio.

Proprietà del processo figlio

Di seguito sono riportate alcune delle proprietà che detiene un processo figlio:

  1. I contatori della CPU e gli utilizzi delle risorse vengono inizializzati per essere reimpostati a zero.
  2. Quando il processo padre viene terminato, i processi figlio non ricevono alcun segnale perché l'attributo PR_SET_PDEATHSIG in prctl() viene reimpostato.
  3. Il thread utilizzato per chiamare fork() crea il processo figlio. Quindi l'indirizzo del processo figlio sarà lo stesso di quello del genitore.
  4. Il descrittore di file del processo padre è ereditato dal processo figlio. Ad esempio l'offset del file o lo stato dei flag e gli attributi di I/O saranno condivisi tra i descrittori di file dei processi figlio e padre. Quindi il descrittore di file della classe genitore farà riferimento allo stesso descrittore di file della classe figlio.
  5. I descrittori della coda dei messaggi aperti del processo padre sono ereditati dal processo figlio. Ad esempio se un descrittore di file contiene un messaggio nel processo padre lo stesso messaggio saràpresente nel corrispondente descrittore di file del processo figlio. Quindi possiamo dire che i valori dei flag di questi descrittori di file sono gli stessi.
  6. Allo stesso modo, i flussi di directory aperti verranno ereditati dai processi figlio.
  7. Il valore predefinito del timer slack della classe figlia è lo stesso del valore corrente del timer slack della classe genitore.

Proprietà che non sono ereditate dal processo figlio

Di seguito sono riportate alcune delle proprietà che non vengono ereditate da un processo figlio:

  1. Blocchi di memoria
  2. Il segnale in sospeso di una classe figlio è vuoto.
  3. Elabora i blocchi dei record associati (fcntl())
  4. Operazioni di I/O asincrone e contenuto di I/O.
  5. Notifiche di modifica della directory.
  6. Timer come alarm(), setitimer() non vengono ereditati dalla classe figlia.

fork() in Do

Non ci sono argomenti in fork() e il tipo restituito di fork() è intero. Devi includere i seguenti file di intestazione quando viene utilizzato fork():

#includere
#includere
#includere

Quando si lavora con fork(), può essere usato per il tipo pid_t per gli ID dei processi come pid_t è definito in .

Il file di intestazione è dove fork() è definito quindi devi includerlo nel tuo programma per usare fork().

Il tipo di ritorno è definito in e la chiamata fork() è definita in . Pertanto, è necessario includere entrambi nel programma per utilizzare la chiamata di sistema fork().

Sintassi di fork()

La sintassi della chiamata di sistema fork() in Linux, Ubuntu è la seguente:

pid_t fork(void);

Nella sintassi il tipo restituito è pid_t. Quando il processo figlio viene creato con successo, il PID del processo figlio viene restituito nel processo padre e 0 verrà restituito al processo figlio stesso.

In caso di errore, viene restituito -1 al processo padre e il processo figlio non viene creato not.

Nessun argomento viene passato a fork(). 

Esempio 1: chiamata fork()

Considera il seguente esempio in cui abbiamo usato la chiamata di sistema fork() per creare un nuovo processo figlio:

CODICE:

#includere
#includere
#includere
intero principale()

forchetta();
printf("Uso la chiamata di sistema fork()\n");
restituisce 0;

PRODUZIONE:

Utilizzo della chiamata di sistema fork()
Utilizzo della chiamata di sistema fork()

In questo programma, abbiamo usato fork(), questo creerà un nuovo processo figlio. Quando viene creato il processo figlio, sia il processo padre che il processo figlio punteranno all'istruzione successiva (stesso Program Counter). In questo modo le restanti istruzioni o istruzioni C verranno eseguite per il numero totale di tempi di processo, ovvero 2n volte, dove n è il numero di chiamate di sistema fork().

Quindi quando la chiamata fork() viene usata una volta come sopra (21 = 2) avremo il nostro output 2 volte.

Qui quando viene utilizzata la chiamata di sistema fork(), la struttura interna sarà simile a:

Considera il seguente caso in cui fork() viene utilizzato 4 volte:

CODICE:

#includere
#includere
#includere
intero principale()

forchetta();
forchetta();
forchetta();
forchetta();
printf("Usando la chiamata di sistema fork()");
restituisce 0;

Produzione:

Utilizzo della chiamata di sistema fork() Utilizzo della chiamata di sistema fork() Utilizzo della chiamata di sistema fork() Utilizzo della chiamata di sistema fork() Utilizzo della chiamata di sistema fork() Utilizzo della chiamata di sistema fork() Utilizzo della chiamata di sistema fork() Utilizzo della chiamata di sistema fork() Utilizzo di fork () chiamata di sistema Utilizzo della chiamata di sistema fork() Utilizzo della chiamata di sistema fork() Utilizzo della chiamata di sistema fork() Utilizzo della chiamata di sistema fork() Utilizzo della chiamata di sistema fork() Utilizzo della chiamata di sistema fork() Utilizzo della chiamata di sistema fork() 

Ora il numero totale di processi creati è 24 = 16 e abbiamo la nostra istruzione print eseguita 16 volte.

Esempio 2: test se fork() ha avuto successo

Nell'esempio seguente abbiamo usato il costrutto decisionale per testare il valore (int) restituito da fork(). E vengono visualizzati i messaggi corrispondenti:

CODICE:

#includere
#includere
#includere
intero principale()

pid_t p;
p = fork();
se(p==-1)

printf("Si è verificato un errore durante la chiamata a fork()");

se(p==0)

printf("Siamo nel processo figlio");

altro

printf("Siamo nel processo padre");

restituisce 0;

PRODUZIONE:

Siamo nel processo genitore
Siamo nel processo bambino child

Nell'esempio sopra abbiamo usato il tipo pid_t che memorizzerà il valore di ritorno di fork(). fork() viene chiamato in linea:

p = fork();

Quindi il valore intero restituito da fork() viene memorizzato in p e quindi p viene confrontato per verificare se la nostra chiamata fork() ha avuto successo.

Quando viene utilizzata la chiamata fork() e il figlio viene creato con successo, l'id del processo figlio verrà restituito al processo padre e 0 verrà restituito al processo figlio.L'ID del processo figlio nel processo padre non sarà lo stesso dell'ID del processo figlio nel processo figlio stesso. Nel processo figlio l'ID del processo figlio sarà 0.

Con questo tutorial puoi vedere come iniziare con la chiamata di sistema fork in Linux.

Come installare ed eseguire app Android su Ubuntu usando Anbox
Hai mai pensato di eseguire un'app Android o un gioco sul tuo sistema Linux?? Android e Linux sono parenti stretti e non c'è motivo difficile per cui ...
Come installare il tema Xenlism Minimalism GTK su Ubuntu 18.04 LTS
L'applicazione di temi è un ottimo modo per cambiare l'aspetto del tuo PC. Oggi ti presenteremo un altro tema GTK per il tuo Ubuntu. Il minimalismo di...
Come installare Ubuntu completo su un'unità flash USB
In questo tutorial, eseguiremo un'installazione completa di Ubuntu su un'unità flash USB. Nota che non si tratta solo di creare un'unità USB Ubuntu Li...