fork (), vfork (), exec () 및 clone ()의 차이점
Google 에서이 4 가지의 차이점을 찾고 있었고이 정보에 대한 많은 양의 정보가있을 것으로 예상했지만 실제로는 4 개의 통화 사이에 확실한 비교가 없었습니다.
이러한 시스템 호출의 차이점을 살펴보면 일종의 기본 개요를 한눈에 살펴볼 수 있습니다. 이 모든 정보가 정확합니까 / 중요한 것이 누락 되었습니까?
Fork
: 포크 호출은 기본적으로 현재 프로세스의 복제본을 거의 모든 방식으로 동일하게 만듭니다 (예를 들어, 일부 구현에서 자원 제한과 같은 모든 것이 복사되지는 않지만 가능한 한 사본을 작성하는 아이디어입니다).
새 프로세스 (자식)는 다른 프로세스 ID (PID)를 가져오고 이전 프로세스 (부모)의 PID를 상위 PID (PPID)로 갖습니다. 두 프로세스가 이제 정확히 동일한 코드를 실행하고 있기 때문에 fork의 리턴 코드를 통해 어떤 프로세스가 어떤 것인지 알 수 있습니다. 하위는 0이되고 상위는 하위의 PID를 가져옵니다. 이것은 물론 포크 호출이 작동한다고 가정합니다. 그렇지 않으면 자식이 생성되지 않고 부모가 오류 코드를 얻습니다.
Vfork
vfork와 fork의 기본 차이점은 vfork ()를 사용하여 새 프로세스를 만들 때 부모 프로세스가 일시적으로 중단되고 자식 프로세스가 부모의 주소 공간을 빌릴 수 있다는 것입니다. 이 이상한 상황은 자식 프로세스가 종료되거나 execve ()를 호출 할 때까지 계속되며,이 때 부모 프로세스는 계속됩니다.
즉, vfork ()의 자식 프로세스는 부모 프로세스의 변수를 예기치 않게 수정하지 않도록주의해야합니다. 특히, 자식 프로세스는 vfork () 호출을 포함하는 함수에서 리턴해서는 안되며 exit ()를 호출하지 않아야합니다 (종료해야하는 경우 _exit ()를 사용해야합니다. 실제로, 이는 자식에 대해서도 마찬가지입니다. 일반 포크 ()).
Exec :
exec 호출은 기본적으로 현재 프로세스 전체를 새로운 프로그램으로 대체하는 방법입니다. 프로그램을 현재 프로세스 공간으로로드하고 진입 점에서 실행합니다. exec ()는 현재 프로세스를 함수가 가리키는 실행 파일로 바꿉니다. exec () 오류가 없으면 컨트롤은 원래 프로그램으로 돌아 가지 않습니다.
Clone :
클론은 포크로서 새로운 프로세스를 만듭니다. 포크와 달리, 이러한 호출을 통해 하위 프로세스는 메모리 공간, 파일 디스크립터 테이블 및 신호 핸들러 테이블과 같은 실행 컨텍스트의 일부를 호출 프로세스와 공유 할 수 있습니다.
자식 프로세스가 clone으로 생성되면 함수 응용 프로그램 fn (arg)이 실행됩니다. (이것은 원래 포크 호출 시점부터 자식에서 실행이 계속되는 포크와 다릅니다.) fn 인수는 실행 시작시 자식 프로세스가 호출하는 함수에 대한 포인터입니다. arg 인수는 fn 함수로 전달됩니다.
fn (arg) 함수 응용 프로그램이 리턴되면 하위 프로세스가 종료됩니다. fn에 의해 리턴 된 정수는 하위 프로세스의 종료 코드입니다. 하위 프로세스는 exit (2)를 호출하거나 치명적 신호를 수신 한 후 명시 적으로 종료 될 수도 있습니다.
입수 한 정보 :
- 포크와 exec의 차이점
- http://www.allinterview.com/showanswers/59616.html
- http://www.unixguide.net/unix/programming/1.1.2.shtml
- http://linux.about.com/library/cmd/blcmdl2_clone.htm
이것을 읽어 주셔서 감사합니다! :)
vfork()
사용되지 않는 최적화입니다. 좋은 메모리 관리 전에fork()
부모의 메모리를 완전히 복사하여 비용이 많이 들었습니다. 많은 경우에 현재 메모리 맵을 버리고 새로운 맵을 생성하는 afork()
가 뒤에exec()
오기 때문에 불필요한 비용이 들었습니다. 요즘에는fork()
메모리를 복사하지 않습니다. 그것은 단순히 때문에, "쓰기 복사"로 설정되어fork()
+는exec()
효율적으로 그냥vfork()
+exec()
.clone()
에서 사용하는 syscallfork()
입니다. 일부 매개 변수를 사용하면 새 프로세스를 만들고 다른 매개 변수를 사용하면 스레드를 만듭니다. 이들의 차이점은 메모리 공간, 프로세서 상태, 스택, PID, 열린 파일 등의 데이터 구조가 공유되는지 여부입니다.
execve()
현재 실행 가능 이미지를 실행 파일에서로드 된 다른 이미지로 대체합니다.fork()
자식 프로세스를 만듭니다.vfork()
의 최적화 된 이전 버전fork()
으로을 (를)execve()
바로 다음에 호출 할 때 사용됩니다fork()
. MMU가 아닌 시스템 (fork()
효율적인 방식으로 작동 할 수없는 시스템 )과fork()
작은 프로그램을 실행하기 위해 메모리 공간이 큰 프로세스를 처리 할 때 잘 작동하는 것으로 나타났습니다 (Java 생각Runtime.exec()
). POSIX는posix_spawn()
이 후자를 두 가지 더 현대적인 용도로 대체하도록 표준화했습니다vfork()
.posix_spawn()
는 afork()/execve()
와 동등하며 일부 fd 사이에서 저글링을 허용합니다.fork()/execve()
주로 비 MMU 플랫폼의 경우을 대체해야합니다 .pthread_create()
새로운 스레드를 만듭니다.clone()
는 Linux 전용 호출이며에서fork()
까지 구현하는 데 사용할 수 있습니다pthread_create()
. 그것은 많은 통제권을줍니다. 에 영감을 받았습니다rfork()
.rfork()
Plan-9 전용 통화입니다. 전체 프로세스와 스레드간에 여러 수준의 공유를 허용하는 일반 호출이어야합니다.
fork()
-부모 프로세스의 전체 사본 인 새 자식 프로세스를 만듭니다. 자식 프로세스와 부모 프로세스는 서로 다른 가상 주소 공간을 사용하며 처음에는 동일한 메모리 페이지로 채워집니다. 그런 다음 두 프로세스가 실행될 때 운영 체제가이 두 프로세스 중 하나에 의해 작성되는 메모리 페이지의 지연 복사를 수행하고 수정 된 페이지의 독립적 인 사본을 할당하기 때문에 가상 주소 공간이 점점 더 달라지기 시작합니다. 각 프로세스에 대한 메모리. 이 기술을 COW (Copy-On-Write)라고합니다.vfork()
-부모 프로세스의 "빠른"복사 본인 새 자식 프로세스를 만듭니다. 시스템 호출과 달리fork()
자식 프로세스와 부모 프로세스는 동일한 가상 주소 공간을 공유합니다. 노트! 동일한 가상 주소 공간을 사용하면 부모와 자식 모두 클래식의 경우와 동일한 스택, 스택 포인터 및 명령 포인터를 사용합니다fork()
! 동일한 스택을 사용하는 부모와 자식 간의 원치 않는 간섭을 방지하기 위해 자식 프로세스가 호출exec()
(새 가상 주소 공간 생성 및 다른 스택으로의 전환) 또는_exit()
프로세스 실행 종료 까지 부모 프로세스 실행이 고정됩니다. ). "fork-and-exec"모델vfork()
의 최적화입니다fork()
.fork()
와 달리 4-5 배 빠르게 수행 할 수 있습니다 .fork()
(COW를 염두에두고도)vfork()
시스템 호출 구현 에는 새 주소 공간 작성 (새 페이지 디렉토리의 할당 및 설정)이 포함되지 않습니다.clone()
-새로운 자식 프로세스를 만듭니다. 이 시스템 호출의 다양한 매개 변수는 상위 프로세스의 어떤 부분이 하위 프로세스에 복사되어야하는지와 그 사이에서 공유 될 부분을 지정합니다. 결과적으로이 시스템 호출을 사용하여 스레드에서 시작하여 완전히 독립적 인 프로세스로 마무리하는 모든 종류의 실행 엔터티를 만들 수 있습니다. 실제로,clone()
시스템 호출은 시스템 호출의pthread_create()
모든 패밀리 및 구현에 사용되는 기본입니다fork()
.exec()
- resets all the memory of the process, loads and parses specified executable binary, sets up new stack and passes control to the entry point of the loaded executable. This system call never return control to the caller and serves for loading of a new program to the already existing process. This system call withfork()
system call together form a classical UNIX process management model called "fork-and-exec".
The fork(),vfork() and clone() all call the do_fork() to do the real work, but with different parameters.
asmlinkage int sys_fork(struct pt_regs regs)
{
return do_fork(SIGCHLD, regs.esp, ®s, 0);
}
asmlinkage int sys_clone(struct pt_regs regs)
{
unsigned long clone_flags;
unsigned long newsp;
clone_flags = regs.ebx;
newsp = regs.ecx;
if (!newsp)
newsp = regs.esp;
return do_fork(clone_flags, newsp, ®s, 0);
}
asmlinkage int sys_vfork(struct pt_regs regs)
{
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, ®s, 0);
}
#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
#define CLONE_VM 0x00000100 /* set if VM shared between processes */
SIGCHLD means the child should send this signal to its father when exit.
For fork, the child and father has the independent VM page table, but since the efficiency, fork will not really copy any pages, it just set all the writeable pages to readonly for child process. So when child process want to write something on that page, an page exception happen and kernel will alloc a new page cloned from the old page with write permission. That's called "copy on write".
For vfork, the virtual memory is exactly by child and father---just because of that, father and child can't be awake concurrently since they will influence each other. So the father will sleep at the end of "do_fork()" and awake when child call exit() or execve() since then it will own new page table. Here is the code(in do_fork()) that the father sleep.
if ((clone_flags & CLONE_VFORK) && (retval > 0))
down(&sem);
return retval;
Here is the code(in mm_release() called by exit() and execve()) which awake the father.
up(tsk->p_opptr->vfork_sem);
For sys_clone(), it is more flexible since you can input any clone_flags to it. So pthread_create() call this system call with many clone_flags:
int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL | CLONE_SETTLS | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID | CLONE_SYSVSEM);
Summary: the fork(),vfork() and clone() will create child processes with different mount of sharing resource with the father process. We also can say the vfork() and clone() can create threads(actually they are processes since they have independent task_struct) since they share the VM page table with father process.
in fork(), either child or parent process will execute based on cpu selection.. But in vfork(), surely child will execute first. after child terminated, parent will execute.
참고URL : https://stackoverflow.com/questions/4856255/the-difference-between-fork-vfork-exec-and-clone
'IT' 카테고리의 다른 글
D3 데이텀과 데이터의 차이점은 무엇입니까? (0) | 2020.05.15 |
---|---|
신속한 언어의 오류 처리 (0) | 2020.05.15 |
R은 패키지를 어디에 저장합니까? (0) | 2020.05.15 |
SQL Server 쿼리 캐시를 지우려면 어떻게해야합니까? (0) | 2020.05.15 |
Maven“Module”과“Project”(Eclipse, m2eclipse 플러그인) (0) | 2020.05.15 |