GNU/Linux >> Linux Esercitazione >  >> Linux

Fork vs Clone su 2.6 Kernel Linux

fork() era la chiamata di sistema UNIX originale. Può essere utilizzato solo per creare nuovi processi, non thread. Inoltre, è portatile.

In Linux, clone() è una nuova e versatile chiamata di sistema che può essere utilizzata per creare un nuovo thread di esecuzione. A seconda delle opzioni passate, il nuovo thread di esecuzione può aderire alla semantica di un processo UNIX, un thread POSIX, una via di mezzo o qualcosa di completamente diverso (come un contenitore diverso). Puoi specificare tutti i tipi di opzioni che stabiliscono se la memoria, i descrittori di file, i vari spazi dei nomi, i gestori di segnale e così via vengono condivisi o copiati.

Dal clone() è la chiamata di sistema superset, l'implementazione del fork() il wrapper delle chiamate di sistema in glibc chiama effettivamente clone() , ma questo è un dettaglio di implementazione che i programmatori non devono conoscere. Il vero fork() la chiamata di sistema esiste ancora nel kernel di Linux per ragioni di compatibilità con le versioni precedenti, anche se è diventata ridondante, perché i programmi che utilizzano versioni molto vecchie di libc, o un'altra libc oltre a glibc, potrebbero utilizzarla.

clone() è anche usato per implementare il pthread_create() Funzione POSIX per la creazione di thread.

I programmi portabili dovrebbero chiamare fork() e pthread_create() , non clone() .


Sembra che ci siano due clone() cose che circolano in Linux 2.6

C'è una chiamata di sistema:

int clone(int (*fn)(void *), void *child_stack,
          int flags, void *arg, ...
          /* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );

Questo è il "clone()" descritto facendo man 2 clone .

Se leggi quella pagina man abbastanza da vicino, vedrai questo:

It is actually a library function layered on top of the
underlying clone() system call.

Apparentemente, dovresti implementare il threading usando la "funzione di libreria" sovrapposta alla chiamata di sistema dal nome identico e confuso.

Ho scritto un breve programma:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int
main(int ac, char **av)
{
    pid_t cpid;
    switch (cpid = fork()) {
    case 0:   // Child process
        break;
    case -1:  // Error
        break;
    default:  // parent process
        break;
    }
    return 0;
}

Compilato con:c99 -Wall -Wextra e l'ho eseguito in strace -f per vedere cosa fanno effettivamente le chiamate di sistema che si diramano. L'ho preso da strace su una macchina Linux 2.6.18 (CPU x86_64):

20097 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x2b4ee9213770) = 20098
20097 exit_group(0)                     = ?
20098 exit_group(0)

Nessuna chiamata "fork" appare nel strace produzione. Il clone() chiamata che compare nel strace output ha argomenti molto diversi da man-page-clone. child_stack=0 poiché il primo argomento è diverso da int (*fn)(void *) .

Sembra che il file fork(2) la chiamata di sistema è implementata in termini di reale clone() , proprio come la "funzione libreria" clone() è implementato. Il reale clone() ha un diverso set di argomenti rispetto a man-page-clone.

Semplificando, entrambe le tue affermazioni apparentemente contraddittorie su fork() e clone() sono corretti. Il "clone" coinvolto è diverso, però.


fork() è solo un particolare insieme di flag per la chiamata di sistema clone() . clone() è abbastanza generale da creare un "processo" o un "thread" o anche cose strane che si trovano da qualche parte tra processi e thread (ad esempio, diversi "processi" che condividono la stessa tabella di descrittori di file).

Essenzialmente, per ogni "tipo" di informazione associata a un contesto di esecuzione nel kernel, clone() ti dà la scelta di aliasare tali informazioni o copiarle. I thread corrispondono all'aliasing, i processi corrispondono alla copia. Specificando combinazioni intermedie di flag a clone() , puoi creare cose strane che non sono thread o processi. Di solito non dovresti farlo, e immagino ci sia stato qualche dibattito durante lo sviluppo del kernel Linux sul fatto che dovrebbe consentire un meccanismo generale come clone() .


Linux
  1. Il ciclo di vita dei test del kernel Linux

  2. Come aggiornare il kernel su desktop Linux

  3. Linux:metodi di chiamata di sistema nel nuovo kernel?

  4. Linux – I diversi kernel Linux/unix sono intercambiabili?

  5. Chiama una funzione dello spazio utente dall'interno di un modulo del kernel Linux

Linux è un sistema operativo o un kernel?

Kernel Linux vs. Kernel Mac

Kernel Linux e le sue funzioni

Cosa fare in caso di panico del kernel Linux

Guida completa alla registrazione di Linux

Linux:diagramma del kernel Linux vs. Strumenti per le prestazioni?