Dường như có hai clone()thứ trôi nổi trong Linux 2.6
Có một cuộc gọi hệ thống:
int clone(int (*fn)(void *), void *child_stack,
int flags, void *arg, ...
/* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );
Đây là "clone ()" được mô tả bằng cách làm man 2 clone.
Nếu bạn đọc trang người đàn ông đó đủ gần, bạn sẽ thấy điều này:
It is actually a library function layered on top of the
underlying clone() system call.
Rõ ràng, bạn phải thực hiện phân luồng bằng cách sử dụng "chức năng thư viện" được xếp lớp trên lệnh gọi hệ thống có tên khó hiểu.
Tôi đã viết một chương trình ngắn:
#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;
}
Biên dịch nó với : c99 -Wall -Wextra, và chạy nó bên dưới strace -fđể xem những gì hệ thống gọi forking thực sự làm. Tôi đã nhận được điều này stracetrên một máy 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)
Không có cuộc gọi "ngã ba" nào xuất hiện trong straceđầu ra. Cuộc clone()gọi hiển thị trong straceđầu ra có các đối số rất khác với man-page-clone. child_stack=0như đối số đầu tiên là khác nhau int (*fn)(void *).
Dường như fork(2)cuộc gọi hệ thống được triển khai theo nghĩa thực clone() , giống như "chức năng thư viện" clone()được triển khai. Thực tế clone() có một tập hợp các đối số khác nhau từ bản sao con người.
Nói một cách đơn giản, cả hai tuyên bố rõ ràng mâu thuẫn của bạn về fork()và clone()đều đúng. "Bản sao" liên quan là khác nhau, mặc dù.