Qual'è la differenza tra fork e thread?


Risposte:


94

Un fork ti dà un processo nuovo di zecca, che è una copia del processo corrente, con gli stessi segmenti di codice. Man mano che l'immagine della memoria cambia (in genere ciò è dovuto al diverso comportamento dei due processi) si ottiene una separazione delle immagini della memoria (Copia su scrittura), tuttavia il codice eseguibile rimane lo stesso. Le attività non condividono la memoria a meno che non utilizzino una primitiva IPC (Inter Process Communication) .

Un processo può avere più thread, ciascuno eseguito in parallelo nello stesso contesto del processo. La memoria e altre risorse sono condivise tra i thread, pertanto è necessario accedere ai dati condivisi tramite alcuni oggetti primitivi e di sincronizzazione (come mutex , variabili di condizione e semafori ) che consentono di evitare il danneggiamento dei dati.


3
Probabilmente vorrai fare riferimento alla "copia del processo corrente" come a un processo figlio.

1
Il segmento di testo tuttavia è spesso condiviso (virtualmente) e anche il segmento di dati può essere copiato su scrittura.
Jé Queue


76

Forchetta

Fork non è altro che un nuovo processo che assomiglia esattamente al vecchio o al processo genitore, ma è comunque un processo diverso con un ID di processo diverso e con una propria memoria. Il processo padre crea uno spazio di indirizzi separato per il figlio. Entrambi i processi padre e figlio possiedono lo stesso segmento di codice, ma vengono eseguiti indipendentemente l'uno dall'altro.

L'esempio più semplice di fork è quando esegui un comando sulla shell in Unix / Linux. Ogni volta che un utente emette un comando, la shell esegue il fork di un processo figlio e l'attività viene eseguita.

Quando viene emessa una chiamata di sistema fork, viene creata una copia di tutte le pagine corrispondenti al processo padre, caricata in una posizione di memoria separata dal sistema operativo per il processo figlio, ma in alcuni casi ciò non è necessario. Come nelle chiamate di sistema "exec", non è necessario copiare le pagine del processo genitore, poiché execv sostituisce lo spazio degli indirizzi del processo genitore stesso.

Poche cose da notare sul fork sono:

  • Il processo figlio avrà il proprio ID processo univoco.
  • Il processo figlio deve avere una propria copia del descrittore di file del genitore.
  • I blocchi di file impostati dal processo genitore non devono essere ereditati dal processo figlio.
  • Tutti i semafori aperti nel processo genitore devono essere aperti anche nel processo figlio.
  • Il processo figlio deve avere una propria copia dei descrittori della coda di messaggi del genitore.
  • Il bambino avrà il proprio spazio di indirizzi e la propria memoria.

Discussioni

I thread sono processi leggeri (LWP). Tradizionalmente, un thread è solo uno stato della CPU (e qualche altro stato minimo) con il processo che contiene il resto (dati, stack, I / O, segnali). I thread richiedono meno overhead rispetto al "fork" o alla generazione di un nuovo processo perché il sistema non inizializza un nuovo spazio di memoria virtuale del sistema e l'ambiente per il processo. Sebbene sia più efficace su un sistema multiprocessore in cui il flusso di processo può essere programmato per essere eseguito su un altro processore guadagnando così velocità attraverso l'elaborazione parallela o distribuita, i vantaggi si trovano anche su sistemi monoprocessore che sfruttano la latenza nell'I / O e altre funzioni di sistema che possono arrestare il processo esecuzione.

I thread nello stesso processo condividono:

  • istruzioni di processo
  • la maggior parte dei dati
  • file aperti (descrittori)
  • segnali e gestori di segnali
  • directory di lavoro corrente
  • ID utente e gruppo

Maggiori dettagli possono essere trovati qui .


2
Un processo può avere diversi thread. Se uno dei thread in un processo chiama fork, il processo forkato ha una memoria completamente duplicata, ma solo il thread chiamante è nel nuovo processo?
Michael


29

La risposta di Dacav è eccellente, volevo solo aggiungere che non tutti i modelli di threading offrono una vera multi-elaborazione.

Ad esempio, l'implementazione predefinita del threading di Ruby non utilizza veri thread del sistema operativo / kernel. Invece imita avere più thread passando tra gli oggetti Thread all'interno di un singolo thread / processo del kernel.

Questo è importante su sistemi multiprocessore / multi-core, perché questi tipi di thread leggeri possono essere eseguiti solo su un singolo core: non si ottiene molto in termini di aumento delle prestazioni dall'avere più thread.

L'altro posto in cui questo fa la differenza è quando un thread si blocca (in attesa di I / O o chiamando l'IOCTL di un driver), tutti i thread si bloccano.

Questo non è molto comune al giorno d'oggi - la maggior parte delle implementazioni di threading utilizza thread del kernel che non soffrono di questi problemi - ma vale la pena menzionarlo per completezza.

Al contrario, fork ti dà un altro processo che può essere eseguito simultaneamente su un'altra CPU fisica mentre il processo originale è in esecuzione. Alcune persone trovano IPC più adatto alla loro app, altri preferiscono il threading.

Buona fortuna e buon divertimento! Il multi-threading è sia stimolante che gratificante.


7
+1 per aver colpito un nervo: "non tutti i thread ti danno un vero multiprocessing"
Dacav

5

I thread sono funzioni eseguite in parallelo, fork è un nuovo processo con ereditarietà dei genitori. I thread sono utili per eseguire un'attività in parallelo, mentre i fork sono processi indipendenti, anch'essi in esecuzione simultaneamente. I thread hanno condizioni di gara e lì controlla semafori e lock o mutex, i tubi possono essere utilizzati sia in fork che in thread.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.