Wygląda na to, że clone()
w Linuksie 2.6 krążą dwie rzeczy
Jest wywołanie systemowe:
int clone(int (*fn)(void *), void *child_stack,
int flags, void *arg, ...
/* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );
Jest to „clone ()” opisane przez działanie man 2 clone
.
Jeśli przeczytasz tę stronę podręcznika wystarczająco blisko, zobaczysz to:
It is actually a library function layered on top of the
underlying clone() system call.
Najwyraźniej należy wdrożyć wątki za pomocą „funkcji bibliotecznej” warstwowej w myląco identycznej nazwie wywołania systemowego.
Napisałem krótki program:
#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;
}
Skompilowałem go za pomocą: c99 -Wall -Wextra
i uruchomiłem pod nim, strace -f
aby zobaczyć, co faktycznie robi rozwiązywanie połączeń systemowych. Mam to na komputerze z strace
systemem Linux 2.6.18 (procesor 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)
Na strace
wyjściu nie pojawia się wywołanie „fork” . clone()
Wezwanie, które pojawia się w strace
produkcji ma bardzo różne argumenty od człowieka-page-klon. child_stack=0
ponieważ pierwszy argument jest inny niż int (*fn)(void *)
.
Wygląda na to, że fork(2)
wywołanie systemowe zostało zaimplementowane w kategoriach rzeczywistych clone()
, podobnie jak clone()
zaimplementowana została „funkcja biblioteczna” . Prawdziwy clone()
ma inny zestaw argumentów od człowieka-page-klon.
Upraszczając, oba twoje pozornie sprzeczne stwierdzenia dotyczące fork()
i clone()
są prawidłowe. Jednak zaangażowany „klon” jest inny.