Linux utilise un modèle de thread 1-1, avec (pour le noyau) aucune distinction entre les processus et les threads - tout est simplement une tâche exécutable. *
Sous Linux, l'appel système clone
clone une tâche, avec un niveau de partage configurable, parmi lesquels:
CLONE_FILES
: partage la même table de descripteurs de fichiers (au lieu de créer une copie)
CLONE_PARENT
: ne pas établir de relation parent-enfant entre la nouvelle tâche et l'ancienne (sinon, child getppid()
= parent's getpid()
)
CLONE_VM
: partager le même espace mémoire (au lieu de créer une copie COW )
fork()
appelle le clone(
moins de partage )
et pthread_create()
appelle le clone(
plus de partage )
. **
fork
ing coûte un tout petit peu plus pthread_create
qu'ing en raison de la copie des tables et de la création de mappages COW pour la mémoire, mais les développeurs du noyau Linux ont essayé (et réussi) à minimiser ces coûts.
La commutation entre les tâches, si elles partagent le même espace mémoire et différentes tables, sera un peu moins chère que si elles ne sont pas partagées, car les données peuvent déjà être chargées dans le cache. Cependant, le changement de tâches est toujours très rapide même si rien n'est partagé - c'est autre chose que les développeurs du noyau Linux essaient d'assurer (et réussissent à assurer).
En fait, si vous êtes sur un système multiprocesseur, le non- partage peut en fait être bénéfique pour les performances: si chaque tâche s'exécute sur un processeur différent, la synchronisation de la mémoire partagée coûte cher.
* Simplifié. CLONE_THREAD
provoque la distribution des signaux à partager (qui a besoin CLONE_SIGHAND
, qui partage la table de gestion des signaux).
** Simplifié. Il existe à la fois SYS_fork
et SYS_clone
syscalls, mais dans le noyau, les sys_fork
et sys_clone
sont à la fois des wrappers très fins autour de la même do_fork
fonction, qui est elle-même un wrapper mince copy_process
. Oui, les termes process
, thread
et task
sont utilisés de manière plutôt interchangeable dans le noyau Linux ...