Es scheint, dass clone()
in Linux 2.6 zwei Dinge im Umlauf sind
Es gibt einen Systemaufruf:
int clone(int (*fn)(void *), void *child_stack,
int flags, void *arg, ...
/* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );
Dies ist der "clone ()", der durch "doing" beschrieben wird man 2 clone
.
Wenn Sie diese Manpage nah genug gelesen haben, sehen Sie Folgendes:
It is actually a library function layered on top of the
underlying clone() system call.
Anscheinend soll das Threading mithilfe der "Bibliotheksfunktion" implementiert werden, die auf dem verwirrend identisch benannten Systemaufruf liegt.
Ich habe ein kurzes Programm geschrieben:
#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;
}
Kompilierte es mit: c99 -Wall -Wextra
und ließ es unter strace -f
laufen, um zu sehen, was Systemaufrufe tatsächlich tun. Ich habe dies strace
auf einem Linux 2.6.18-Rechner (x86_64-CPU) herausgefunden:
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)
In der strace
Ausgabe erscheint kein "Fork" -Aufruf. Der clone()
in der strace
Ausgabe angezeigte Aufruf hat ganz andere Argumente als der Manpage-Klon. child_stack=0
als erstes argument ist anders als int (*fn)(void *)
.
Es scheint, dass der fork(2)
Systemaufruf in Bezug auf den Real implementiert ist clone()
, genau wie die "Bibliotheksfunktion" clone()
implementiert ist. Der Real clone()
hat andere Argumente als der Manpage-Klon.
Vereinfacht gesagt, sind beide Ihrer scheinbar widersprüchlichen Aussagen zu fork()
und clone()
richtig. Der "Klon" ist jedoch anders.