Date création : 27-03-2008 20:23:44
 Vous êtes dans : GNU/Linux Astuces / Pages man [Section2 - Appels système]
CLONE
Index
- NOM
- SYNOPSIS
- DESCRIPTION
- sys_clone
- VALEUR RENVOYÉE
- ERREURS
- DISPONIBILITÉ
- NOTES
- CONFORMITÉ
- BOGUES
- VOIR AUSSI
- TRADUCTION
NOM
clone - Créer un processus fils (child)
SYNOPSIS
#include <sched.h>
int clone(int (*fn)(void *), void *child_stack, int flags, void *arg);
_syscall2(int, clone, int, flags, void *, child_stack)
_syscall5(int, clone, int, flags, void *, child_stack,
int *, parent_tidptr, struct user_desc *, newtls,
int *, child_tidptr)
/* Il peut être préférable d'utiliser syscall(2) ; voir intro(2) */
DESCRIPTION
clone() crée un nouveau processus, exactement comme le fait
fork(2). clone() est une fonction de bibliothèque s'appuyant sur
l'appel système clone() sous-jacent, mentionné comme sys_clone
ci-dessous. Une description de sys_clone se trouve plus bas sur cette
page.
Contrairement à fork(2), cette routine permet le partage d'une partie du
contexte d'exécution entre le processus fils et le processus appelant. Le
partage peut s'appliquer sur l'espace mémoire, sur la table des descripteurs
de fichiers ou la table des gestionnaires de signaux. (Notez que sur cette
page de manuel, le « processus appelant » correspond normalement au « processus père », mais voyez quand même la description de CLONE_PARENT
plus bas).
L'appel système clone() est principalement utilisé pour permettre
l'implémentation des threads : un programme est scindé en plusieurs lignes
de contrôle, s'exécutant simultanément dans un espace mémoire partagée.
Quand le processus fils est créé, avec clone(), il exécute la fonction
fn(arg) de l'application. (Ceci est différent de fork(2) avec
lequel l'exécution continue dans le fils au point de l'appel fork.)
L'argument fn est un pointeur sur la fonction appelée par le processus
fils lors de son démarrage. L'argument arg est transmis à la fonction
fn lors de son invocation.
Quand la fonction fn(arg) revient, le processus fils se termine. La
valeur entière renvoyée par fn est utilisée comme code de retour du
processus fils. Ce dernier peut également se terminer de manière explicite
en invoquant la fonction exit(2) ou après la réception d'un signal fatal.
L'argument child_stack indique l'emplacement de la pile utilisée par le
processus fils. Comme les processus fils et appelant peuvent partager de la
mémoire, il n'est généralement pas possible pour le fils d'utiliser la même
pile que son père. Le processus appelant doit donc préparer un espace
mémoire pour stocker la pile de son fils, et transmettre à clone un
pointeur sur cet emplacement. Les piles croissent vers le bas sur tous les
processeurs implémentant Linux (sauf le HP PA), donc child_stack doit
pointer sur la plus haute adresse de l'espace mémoire prévu pour la pile du
processus fils.
L'octet de poids faible de flags contient le numéro du signal qui sera
envoyé au père lorsque le processus fils se terminera. Si ce signal est
différent de SIGCHLD, le processus parent doit également spécifier les
options __WALL ou __WCLONE lorsqu'il attend la fin du fils avec
wait(2). Si aucun signal n'est indiqué, le processus parent ne sera pas
notifié de la terminaison du fils.
flags permet également de préciser ce qui sera partagé entre le père et
le fils, en effectuant un OU binaire entre une ou plusieurs des constantes
suivantes :
- CLONE_PARENT (depuis Linux 2.3.12)
-
Si CLONE_PARENT est présent, le père du nouveau fils (comme il est
indiqué par getppid(2)) sera le même que celui du processus appelant.
Si CLONE_PARENT n'est pas fourni, alors (comme pour fork(2)) le père
du processus fils sera le processus appelant.
Remarquez que c'est le processus père, tel qu'indiqué par getppid(2), qui
est notifié lors de la fin du fils. Ainsi, si CLONE_PARENT est présent,
alors c'est le père du processus appelant, et non ce dernier, qui sera
notifié.
- CLONE_FS
-
Si l'attribut CLONE_FS est positionné, les processus appelant et fils
partagent les mêmes informations concernant le système de fichiers. Ceci
inclut la racine du système de fichiers, le répertoire de travail, et
l'umask. Tout appel à chroot(2), chdir(2) ou umask(2) effectué par
un processus aura également influence sur l'autre processus.
Si CLONE_FS n'est pas choisi, le processus travaille sur une copie des
informations de l'appelant concernant le système de fichiers. Cette copie
est effectuée lors de l'invocation de clone(). Les appels à chroot(2),
chdir(2), umask(2) effectués par un processus n'affectent pas l'autre
processus.
- CLONE_FILES
-
Si l'attribut CLONE_FILES est positionné, les processus appelant et fils
partagent la même table des descripteurs de fichiers. Tout descripteur créé
par un processus est également valide pour l'autre processus. De même si un
processus ferme un descripteur, ou modifie ses attributs (en utilisant
l'opération fcntl(2) F_SETFD), l'autre processus en est aussi affecté.
Si CLONE_FILES n'est pas positionné, le processus fils hérite d'une copie
des descripteurs de fichiers ouverts par l'appelant au moment de l'appel
clone(). (Les copies des descripteurs de fichiers dans le fils sont
associées aux mêmes descriptions de fichiers ouverts (voir open(2)) que
les descripteurs de fichiers correspondants dans le processus appelant.) Les
opérations effectuées ensuite sur un descripteur par un des processus
n'affectent pas l'autre processus.
- CLONE_NEWNS (depuis Linux 2.4.19)
-
Démarrer le processus dans un nouvel espace de noms.
Chaque processus se trouve dans un espace de noms. Cet espace de noms du
processus regroupe les données décrivant la hiérarchie des fichiers vus par
le processus (l'ensemble des montages). Après un fork(2) ou clone(2)
sans l'attribut CLONE_NEWNS le fils se déroule dans le même espace de nom
que son père. Les appels système mount(2) et umount(2) modifient
l'espace de noms du processus appelant, et affectent ainsi tous les
processus se déroulant dans le même espace, sans affecter les processus se
trouvant dans d'autres espaces.
Après un clone(2) avec l'attribut CLONE_NEWNS le fils cloné démarre
dans un nouvel espace de noms, initialisé avec une copie de l'espace du
père.
Seul un processus privilégié (un processus ayant la capacité CAP_SYS_ADMIN)
peut spécifier l'attribut CLONE_NEWNS. Il n'est pas possible de spécifier
à la fois CLONE_NEWNS et CLONE_FS pour le même appel clone().
- CLONE_SIGHAND
-
Si l'attribut CLONE_SIGHAND est positionné, les processus appelant et
fils partagent la même table des gestionnaires de signaux. Si l'appelant, ou
le fils, appelle sigaction(2) pour modifier le comportement associé à un
signal, ce comportement est également changé pour l'autre
processus. Néanmoins, l'appelant et le fils ont toujours des masques de
signaux distincts, et leurs ensembles de signaux bloqués sont
indépendants. L'un des processus peut donc bloquer un signal en utilisant
sigprocmask(2) sans affecter l'autre processus.
Si CLONE_SIGHAND n'est pas utilisé, le processus fils hérite d'une copie
des gestionnaires de signaux de l'appelant lors de l'invocation de
clone(). Les appels à sigaction(2) effectués ensuite depuis un
processus n'ont pas d'effets sur l'autre processus.
Depuis Linux 2.6.0-test6, l'attribut CLONE_VM doit également être
spécifié dans flags si CLONE_SIGHAND l'est.
- CLONE_PTRACE
-
Si l'attribut CLONE_PTRACE est positionné et si l'appelant est suivi par
un débogueur, alors le fils sera également suivi (voir ptrace(2)).
- CLONE_UNTRACED (depuis Linux 2.5.46)
-
Si l'attribut CLONE_UNTRACED est positionné, alors un processus traçant
le père ne peut pas forcer CLONE_PTRACE pour ce fils.
- CLONE_STOPPED (depuis Linux 2.6.0-test2)
-
Si l'attribut CLONE_STOPPED est positionné, le fils est initialement
stoppé (comme s'il avait reçu le signal SIGSTOP), et doit être relancé en
lui envoyant le signal SIGCONT.
- CLONE_VFORK
-
Si le bit CLONE_VFORK est actif, l'exécution du processus appelant est
suspendue jusqu'à ce que le fils libère ses ressources de mémoire virtuelle
par un appel execve(2) ou _exit(2) (comme avec vfork(2)).
Si CLONE_VFORK n'est pas indiqué, alors les deux processus sont
ordonnancés à partir de la fin de l'appel, et l'application ne doit pas
considérer que l'ordre d'exécution soit déterminé.
- CLONE_VM
-
Si le bit CLONE_VM est actif, les processus père et fils s'exécutent dans
le même espace mémoire. En particulier, les écritures en mémoire effectuées
par l'un des processus sont visibles par l'autre. De même toute projection
en mémoire, ou toute suppression de projection, effectuées avec mmap(2)
ou munmap(2) par l'un des processus affectera également l'autre
processus.
Si CLONE_VM n'est pas actif, le processus fils utilisera une copie
distincte de l'espace mémoire de l'appelant. Le cliché est réalisé lors de
l'invocation de clone(). Les écritures ou les projections de fichiers en
mémoire effectuées par un processus n'affectent pas l'autre processus, comme
cela se passe avec fork(2).
- CLONE_PID (obsolète)
-
Si l'attribut CLONE_PID est positionné, les processus appelant et fils
ont le même numéro de processus. C'est bien pour hacker le système, mais
autrement il n'est plus utilisé. Depuis 2.3.21, cet attribut ne peut être
utilisé que par le processus de démarrage du système (PID 0). Il a disparu
dans Linux 2.5.16.
- CLONE_THREAD (depuis Linux 2.4.0-test8)
-
Si CLONE_THREAD est présent, le fils est placé dans le même groupe de
threads que le processus appelant. Afin de rendre l'explication de
CLONE_THREAD plus lisible, le terme « thread » est utilisé pour parler
des processus dans un même groupe de threads.
Les groupes de threads sont une fonctionnalité ajoutées dans Linux 2.4 pour
supporter la notion POSIX d'ensemble de threads partageant un même PID. En
interne, ce PID partagé est appelé identifiant de groupe de threads
(TGID).Depuis Linux 2.4, l'appel getpid(2) renvoie l'identifiant du
groupe de thread de l'appelant.
Les threads dans un groupe peuvent être distingués par leur identifiant de
thread (TID, unique sur le système). Le TID d'un nouveau thread est renvoyé
par clone() au processus appelant, et un thread peut obtenir son propre
TID en utilisant gettid(2).
Quand clone(2) est appelé sans positionner CLONE_THREAD, le nouveau
thread est placé dans un nouveau groupe de thread dont le TGID est identique
au TID du nouveau thread. Ce thread est le leader du nouveau groupe.
Un nouveau thread créé en utilisant CLONE_THREAD a le même processus père
que l'appelant de clone() (de même qu'avec CLONE_PARENT), ainsi les
appels à getppid(2) renvoient la même valeur à tous les threads dans un
même groupe. Lorsqu'un thread créé avec CLONE_THREAD termine, le thread
qui a appelé clone() pour le créer ne reçoit pas le signal SIGCHLD (ou
autre notification de terminaison) ; de même, l'état d'un tel thread ne
peut être obtenu par wait(2). Le thread est dit détaché.
Lorsque tous les threads d'un groupe de threads terminent, le processus
parent du groupe reçoit un signal SIGCHLD (ou autre indicateur de
terminaison).
Si l'un des threads dans un groupe de threads appelle execve(2), tous les
threads sauf le leader sont tués, et le nouveau programme est exécuté dans
le leader du groupe de threads.
Si l'un des threads dans un groupe crée un fils avec fork(2), n'importe
lequel des threads du groupe peut utiliser wait(2) sur ce fils.
Depuis Linux 2.5.35, l'attribut CLONE_SIGHAND de flags doit être
positionné si CLONE_THREAD l'est.
Un signal peut être envoyé à un groupe de threads dans son ensemble
(c'est-à-dire à un TGID) avec kill(2), ou bien à un thread en
particulier (à un TID) avec tgkill(2).
Les gestions de signaux sont définies au niveau des processus : si un
signal sans gestionnaire est reçu par un thread, il affectera (tuera,
stoppera, relancera, ou sera ignoré par) tous les membres du groupe de
threads.
Chaque thread a son propre masque de signaux, défini par sigprocmask(2),
mais les signaux peuvent être en attente soit pour le processus dans son
ensemble (donc peut être reçu par n'importe lequel des threads du groupe),
quand ils sont envoyés avec kill(2), soit pour un thread particulier,
lorsqu'ils sont envoyés par tgkill(2). Un appel à sigpending(2)
renvoie un ensemble de signaux qui est l'union des processus en attente pour
le processus et ceux en attente pour le thread appelant.
Si kill(2) est utilisé pour envoyer un signal à un groupe de threads, et
si le groupe a installé un gestionnaire pour ce signal, alors le
gestionnaire sera exécuté dans exactement un des membres du groupe de
threads, choisi de façon arbitraire parmi ceux qui n'ont pas bloqué ce
signal. Si plusieurs threads dans un groupe attendent le même signal en
utilisant sigwaitinfo(2), le noyau choisira arbitrairement l'un d'entre
eux pour délivrer le signal envoyé par kill(2).
- CLONE_SYSVSEM (depuis Linux 2.5.10)
-
Si CLONE_SYSVSEM est positionné, le fils et le processus appelant
partagent la même liste de compteurs « undo » pour les sémaphores System V (voir semop(2)). Si cet attribut n'est pas utilisé, le fils a une liste
« undo » séparée, initialement vide.
- CLONE_SETTLS (depuis Linux 2.5.32)
-
Le paramètre newtls est le nouveau descripteur TLS (Thread Local
Storage). (Voir set_thread_area(2).)
- CLONE_PARENT_SETTID (depuis Linux 2.5.49)
-
Enregistrer l'ID du thread enfant à parent_tidptr dans la mémoire du père
et du fils. (Dans Linux 2.5.32-2.5.48 il y a un attribut CLONE_SETTID qui
fait cela.)
- CLONE_CHILD_SETTID (depuis Linux 2.5.49)
-
Enregistrer l'ID du thread enfant à child_tidptr dans la mémoire du fils.
- CLONE_CHILD_CLEARTID (depuis Linux 2.5.49)
-
Effacer l'ID du thread enfant à child_tidptr dans la mémoire du fils
lorsqu'il se termine, et réveiller le futex à cette adresse. L'adresse
concernée peut être modifiée par l'appel système set_tid_address(2). Cela
est utilisé dans les bibliothèques de gestion de threads.
sys_clone
L'appel système sys_clone ressemble plus à fork(2), en ceci que
l'exécution dans le processus fils continue à partir du point d'appel. Ainsi
sys_clone ne nécessite que les arguments flags et child_stack qui
ont la même signification que pour clone(). (Notez que l'ordre de ces
arguments est différent de celui dans clone().)
Une autre différence : pour sys_clone, l'argument child_stack peut
être nul, puisque la sémantique de copie-en-écriture assure que le fils
recevra une copie indépendante des pages de la pile dès qu'un des deux
processus la modifiera. Pour que cela fonctionne, il faut naturellement que
CLONE_VM ne soit pas présent.
Depuis Linux 2.5.49, l'appel système a cinq paramètres. Les deux nouveaux
paramètres sont parent_tidptr qui pointe à l'endroit (dans la mémoire du
père et celle du fils) où l'ID du thread fils sera écrit au cas où
CLONE_PARENT_SETTID serait spécifié, et child_tidptr qui pointe à
l'endroit (dans la mémoire du fils) où l'ID du thread fils sera écrit au cas
où CLONE_CHILD_SETTID serait spécifié.
VALEUR RENVOYÉE
En cas de réussite, le TID du processus fils est renvoyé dans le thread
d'exécution de l'appelant. En cas d'échec, -1 est renvoyé dans le contexte
de l'appelant, aucun fils n'est créé, et errno contiendra le code
d'erreur.
ERREURS
- EAGAIN
-
Trop de processus en cours d'exécution.
- EINVAL
-
CLONE_SIGHAND a été spécifié mais pas CLONE_VM (Depuis Linux
2.6.0-test6.)
- EINVAL
-
CLONE_THREAD a été spécifié mais pas CLONE_SIGHAND (depuis Linux
2.5.35).
- EINVAL
-
Les attributs CLONE_NEWNS et CLONE_FS ont été indiqués simultanément
dans flags.
- EINVAL
-
Renvoyée par clone() quand une valeur nulle a été indiquée pour le
paramètre child_stack.
- ENOMEM
-
Pas assez de mémoire pour copier les parties du contexte du processus
appelant qui doivent être dupliquées, ou pour allouer une structure de tâche
pour le processus fils.
- EPERM
-
CLONE_NEWNS a été spécifié par un processus non root (processus sans
CAP_SYS_ADMIN).
- EPERM
-
CLONE_PID a été réclamé par un processus autre que le processus 0.
DISPONIBILITÉ
Il n'y a pas de définition pour clone() dans la libc5. glibc2 fournit une
définition de clone() comme décrit ici.
NOTES
Dans les noyaux 2.4.x, CLONE_THREAD ne rend pas en général le processus
père de l'appelant père du nouveau thread. Cependant, pour les versions
2.4.7 à 2.4.18 du noyau, l'attribut CLONE_THREAD impliquait
CLONE_PARENT (de même qu'avec les noyaux 2.6).
Sur x86, clone() ne devrait pas être appelé via vsyscall, mais
directement en utilisant int $0x80.
CONFORMITÉ
Les appels système clone() et sys_clone sont spécifiques à Linux et ne
doivent pas être employés dans des programmes portables.
BOGUES
Les versions de la bibliothèque C de GNU (glibc) contenant la bibliothèque
de gestion de threads NPTL contiennent une fonction autour de l'appel
système getpid() qui cache les PIDs. Dans les programmes liés à de telles
bibliothèques, les appels à getpid() peuvent renvoyer la même valeur y
compris pour des threads qui n'ont pas été créés avec CLONE_THREAD (et ne
sont donc pas dans le même groupe de threads). Afin d'obtenir la vérité, il
peut être nécessaire d'utiliser du code tel que :
#include <syscall.h>
pid_t mypid;
mypid = syscall(SYS_getpid);
VOIR AUSSI
fork(2), futex(2), getpid(2), gettid(2), set_thread_area(2),
set_tid_address(2), tkill(2), unshare(2), wait(2),
capabilities(7), pthreads(7)
TRADUCTION
Cette page de manuel a été traduite et mise à jour par
Christophe Blaess <http://www.blaess.fr/christophe/> entre 1996 et 2003,
puis par Alain Portal <aportal AT univ-montp2 DOT fr> jusqu'en 2006.
La traduction de cette page de manuel est basée sur les traductions
disponibles sur http://manpagesfr.free.fr/,
mais est gérée par l'équipe francophone de traduction de Debian
au travers de la liste de discussion debian-l10n-french.
Veuillez signaler toute erreur de traduction par un rapport de bogue sur
le paquet manpages-fr.
Vous pouvez toujours avoir accès à la version anglaise de ce document en
utilisant la commande
« man -L C <section> <page_de_man> ».
|