Parece que há duas clone()
coisas flutuando no Linux 2.6
Há uma chamada do sistema:
int clone(int (*fn)(void *), void *child_stack,
int flags, void *arg, ...
/* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );
Este é o "clone ()" descrito ao fazer man 2 clone
.
Se você ler essa página de manual o suficiente, verá o seguinte:
It is actually a library function layered on top of the
underlying clone() system call.
Aparentemente, você deve implementar o encadeamento usando a "função de biblioteca" em camadas na chamada do sistema com nome idêntico e confuso.
Eu escrevi um pequeno programa:
#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;
}
Compilou-o com:, c99 -Wall -Wextra
e o executou strace -f
para ver o que as chamadas de bifurcação do sistema realmente fazem. Tirei isso de strace
uma máquina 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)
Nenhuma chamada "fork" aparece na strace
saída. A clone()
chamada que aparece na strace
saída tem argumentos muito diferentes do clone da página de manual. child_stack=0
como o primeiro argumento é diferente de int (*fn)(void *)
.
Parece que a fork(2)
chamada do sistema é implementada em termos do real clone()
, assim como a "função de biblioteca" clone()
é implementada. O real clone()
tem um conjunto diferente de argumentos do clone da página de manual.
Simplisticamente, ambas as suas declarações aparentemente contraditórias sobre fork()
e clone()
estão corretas. O "clone" envolvido é diferente, no entanto.