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 strace
trê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=0
như đố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ù.