fork()가 내부적으로 clone()을 호출한다는 것이 사실입니까?
Robert Love(ISBN:0-672-32720-1)의 "Linux Kernel Development, Second Edition" 제3장에서 다음과 같은 내용을 읽었습니다.clone
system call은 Linux에서 스레드를 작성하기 위해 사용됩니다.이제 의 구문은clone
시작 루틴/기능 주소를 전달해야 하는 경우입니다.
그러나 같은 페이지에 다음과 같이 쓰여 있다.fork
콜clone
내부적으로그래서 제 질문은, 어떻게 아이 프로세스가fork
다음 코드 부분의 실행을 시작합니다.fork
호출, 즉 어떻게 시작점으로 기능이 필요하지 않은가?
제공된 링크에 잘못된 정보가 있을 경우 더 나은 링크/리소스로 안내해 주십시오.
이런 질문은 항상 소스코드를 읽어주세요.
glibc에서nptl/sysdeps/unix/sysv/linux/fork.c
(기트허브) (nptl
= Linux용 기본 Posix 스레드)의 구현을 확인할 수 있습니다.fork()
syscall이 아닌, 우리는 마법이 그 안에서 일어나는 것을 볼 수 있다.ARCH_FORK
macro: 이 매크로를 인라인콜로 정의합니다.clone()
에nptl/sysdeps/unix/sysv/linux/x86_64/fork.c
(깃허브).하지만 잠시 기다려 주십시오. 이 버전의 에 함수 또는 스택 포인터가 전달되지 않습니다.clone()
그래, 무슨 일이야?
그럼 다음 구현에 대해 살펴보겠습니다.clone()
그럼 glibc로.안에 있다sysdeps/unix/sysv/linux/x86_64/clone.S
(깃허브).기능 포인터를 자녀의 스택에 저장하고 클론 syscall을 호출하면 새로운 프로세스가 함수를 스택에서 불러온 후 호출하는 것을 알 수 있습니다.
다음과 같이 동작합니다.
clone(void (*fn)(void *), void *stack_pointer)
{
push fn onto stack_pointer
syscall_clone()
if (child) {
pop fn off of stack
fn();
exit();
}
}
그리고.fork()
그건...
fork()
{
...
syscall_clone();
...
}
요약
실제의clone()
syscall은 함수 인수를 받지 않고 반환점부터 계속됩니다.fork()
그래서 둘 다clone()
그리고.fork()
라이브러리의 함수는, 그 주변의 랩퍼입니다.clone()
시스템
문서
설명서의 복사본은 좀 더 솔직합니다.clone()
는 라이브러리 기능과 시스템콜입니다하지만, 저는 약간 오해를 살 수 있다고 생각합니다.clone()
섹션 2와 섹션3이 아닌 섹션2에 있습니다.man 페이지부터:
#include <sched.h>
int clone(int (*fn)(void *), void *child_stack,
int flags, void *arg, ...
/* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );
/* Prototype for the raw system call */
long clone(unsigned long flags, void *child_stack,
void *ptid, void *ctid,
struct pt_regs *regs);
그리고.
이 페이지에서는 양쪽 glibc에 대해 설명합니다.
clone()
래퍼 함수와 그 기반이 되는 시스템콜.메인 텍스트에서는 래퍼 기능에 대해 설명합니다.원시 시스템콜의 차이는 이 페이지의 마지막에 설명되어 있습니다.
마침내.
★★★
clone()
은 " "에 더 " 에 합니다.fork(2)
을 사용하다같이 및 .clone()
이치노또한 인수 순서가 변경됩니다.
@Dietrich는 실장을 보면서 설명을 잘했다.대박이다!어쨌든, 그것을 발견할 수 있는 또 다른 방법이 있습니다.그것은, 「스니프」의 콜을 보는 것입니다.
할 수 요.fork(2)
해 주세요).fork
시스콜
#define WRITE(__fd, __msg) write(__fd, __msg, strlen(__msg))
int main(int argc, char *argv[])
{
pid_t pid;
switch (pid = fork()) {
case -1:
perror("fork:");
exit(EXIT_FAILURE);
break;
case 0:
WRITE(STDOUT_FILENO, "Hi, i'm the child");
exit(EXIT_SUCCESS);
default:
WRITE(STDERR_FILENO, "Heey, parent here!");
exit(EXIT_SUCCESS);
}
return EXIT_SUCCESS;
}
그럼 그 해 .clang -Wall -g fork.c -o fork.out
다음 을 사용해서 실행해보세요.strace
:
strace -Cfo ./fork.strace.log ./fork.out
수신됩니다.-f
아이의 수신합니다).그 후, 그을 「」, 「」, 「」, 「」, 「」에 넣습니다../fork.trace.log
-c
옵션을 선택하면 마지막에 요약이 표시됩니다).Ubuntu 14.04, x86_64 Linux 3.16)입니다.
6915 arch_prctl(ARCH_SET_FS, 0x7fa001a93740) = 0
6915 mprotect(0x7fa00188c000, 16384, PROT_READ) = 0
6915 mprotect(0x600000, 4096, PROT_READ) = 0
6915 mprotect(0x7fa001ab9000, 4096, PROT_READ) = 0
6915 munmap(0x7fa001a96000, 133089) = 0
6915 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fa001a93a10) = 6916
6915 write(2, "Heey, parent here!", 18) = 18
6916 write(1, "Hi, i'm the child", 17 <unfinished ...>
6915 exit_group(0) = ?
6916 <... write resumed> ) = 17
6916 exit_group(0) = ?
6915 +++ exited with 0 +++
6916 +++ exited with 0 +++
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
24.58 0.000029 4 7 mmap
17.80 0.000021 5 4 mprotect
14.41 0.000017 9 2 write
11.02 0.000013 13 1 munmap
11.02 0.000013 4 3 3 access
10.17 0.000012 6 2 open
2.54 0.000003 2 2 fstat
2.54 0.000003 3 1 brk
1.69 0.000002 2 1 read
1.69 0.000002 1 2 close
0.85 0.000001 1 1 clone
0.85 0.000001 1 1 execve
0.85 0.000001 1 1 arch_prctl
------ ----------- ----------- --------- --------- ----------------
100.00 0.000118 28 3 total
'아니오'는 .fork
요 전 요 。 그냥 날것만clone
, 설정되어 있다.syscall, "syscall", "syscall", "syscall", "syscall" 등의 명령어를 합니다.
언급URL : https://stackoverflow.com/questions/18904292/is-it-true-that-fork-calls-clone-internally
'programing' 카테고리의 다른 글
Java에서 사용자 입력을 받는 방법은 무엇입니까? (0) | 2022.07.26 |
---|---|
결과 Vue graphql에 쿼리 특성이 누락됨 (0) | 2022.07.26 |
문자열을 URI로 변환 (0) | 2022.07.26 |
정의보다 상수를 선호할까요? (0) | 2022.07.26 |
Java에 Sorted List가 없는 이유는 무엇입니까? (0) | 2022.07.26 |