Здається, що clone()
в Linux 2.6 плавають дві речі
Є системний виклик:
int clone(int (*fn)(void *), void *child_stack,
int flags, void *arg, ...
/* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );
Це "клон ()", описаний при виконанні man 2 clone
.
Якщо ви прочитаєте сторінку чоловіка досить близько, ви побачите це:
It is actually a library function layered on top of the
underlying clone() system call.
Мабуть, ви повинні реалізовувати потоки за допомогою "бібліотечної функції", покладеної на заплутано однаково названий системний виклик.
Я написав коротку програму:
#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;
}
Скомпілював це з: c99 -Wall -Wextra
і запустив його під, strace -f
щоб побачити, що насправді виконує форкінг викликів. Це я отримав strace
на машині Linux 2.6.18 (x86_64 CPU):
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)
У strace
виході не з'являється виклик "вилки" . clone()
Виклик , який проявляється в strace
виході має дуже різні аргументи від людини-сторінки-клони. child_stack=0
як перший аргумент відрізняється, ніж int (*fn)(void *)
.
Здається, що fork(2)
системний виклик реалізований з точки зору реального clone()
, подібно до того, як clone()
реалізована "функція бібліотеки" . Реального clone()
має інший набір аргументів від людини-сторінки-клони.
Простіше кажучи, обидва ваші, очевидно, суперечливі твердження про fork()
та clone()
є правильними. Хоча "клон" є різним.