기본 프로세스 생성 메커니즘이 포크 인 이유는 무엇입니까?


46

프로세스 작성을위한 UNIX 시스템 호출 인 fork ()는 상위 프로세스를 복사하여 하위 프로세스를 작성합니다. 내 이해는 거의 항상 자식 프로세스의 메모리 공간 (텍스트 세그먼트 포함)을 대체하기 위해 exec ()를 호출한다는 것입니다. fork ()에서 부모의 메모리 공간을 복사하는 것은 항상 낭비 적 인 것처럼 보입니다 (메모리 세그먼트를 복사 할 때 복사하여 포인터 만 복사하면 낭비를 최소화 할 수 있음을 알지만). 어쨌든 프로세스 복제에 왜이 복제 방식이 필요한지 아는 사람이 있습니까?


3
fork(2)리눅스 의 매뉴얼 페이지는 다음과 같이 말합니다 : Under Linux, fork() is implemented using copy-on-write pages, so the only penalty that it incurs is the time and memory required to duplicate the parent's page tables, and to create a unique task structure for the child. 나는 이것이 다른 현대 유닉스 풍미의 경우라고 생각합니다 (그러나 확실하지는 않습니다).
larsks

4
원래의 PDP-11 Unix Realy는 포크 프로세스의 모든 바이트를 실제로 복사했습니다.하지만 64Kb의 실행 파일과 최대 64Kb의 데이터 만 있었기 때문에 1975 년에도 큰 부담이 없었습니다. 1990 년 이래로 모든 유닉스와 유닉스 계열이 COW (Copy-On-Write) 텍스트 세그먼트를 가졌기 때문에 책과 기사가 왜 더 이상 "포크 성능 문제"를 전파하는지 잘 모르겠습니다.
Bruce Ediger

오늘날 포크는 vfork와 비슷한 방식으로 구현됩니다 ( openbsd.org/cgi-bin/… ). 효율적이며 걱정하지 마십시오.
Aki

또한 포크 이후에 실행하지 않거나 최소한 즉시 실행하지 않는 경우가 많이 있습니다. 파이프와 웹 서버를 생각하십시오.
jfg956

당신은 일이 느려질 수 있습니다. 그러나 @cjm에 따르면 Microsoft가 CreateProcess를 사용하는 대안을 살펴보면 CreateProcess가 느리기 때문에 스레드를 조기에 구현해야했습니다. ( select파손 되었기 때문에 스레드도 필요 했지만 또 다른 이야기입니다).
ctrl-alt-delor

답변:


57

인터페이스를 단순화하는 것입니다. 에 대한 대안 fork과는 exec윈도우 같은 것 의 CreateProcess 기능. 얼마나 많은 매개 변수 CreateProcess가 있고 많은 매개 변수 가있는 구조체입니다. 때문입니다 모든 새 과정에 대해 제어 할 수있는가에 전달되어야한다 CreateProcess. 실제로 CreateProcess충분한 매개 변수가 없으므로 Microsoft는 CreateProcessAsUserCreateProcessWithLogonW 를 추가해야했습니다 .

fork/exec모델을 사용하면 모든 매개 변수가 필요하지 않습니다. 대신 프로세스의 특정 속성이에 유지 exec됩니다. 이것은 당신이 할 수 있습니다 fork, 다음 (일반적으로 사용하는 것과 동일한 기능을 사용하여) 당신이 원하는 속성을 어떤 과정을 변경 한 exec . Linux에서는 fork매개 변수 execve가 없으며 3 : 실행할 프로그램, 명령 줄 및 환경이 있습니다. (다른 exec기능이 있지만 execve일반적인 사용 사례를 단순화하기 위해 C 라이브러리에서 제공하는 래퍼 입니다.)

다른 현재 디렉토리와 프로세스를 시작하려면 : fork, chdir, exec.

stdin / stdout :을 ​​리디렉션하려면 fork파일을 닫거나 엽니 다 exec.

당신은 스위치 사용자가 원하는 경우 fork, setuid, exec.

이 모든 것을 필요에 따라 결합 할 수 있습니다. 누군가가 프로세스 속성의 새로운 종류와 함께 온다면, 당신은 변경할 필요가 없습니다 forkexec.

Larsk가 언급했듯이 대부분의 최신 Unix는 COW (Copy-On-Write)를 사용하므로 fork상당한 오버 헤드가 발생하지 않습니다.


16
훌륭한 설명. "유닉스를 이해하지 못하는 사람들은 유닉스를 재발 명하지 않는다고 비난했다." -Henry Spencer
Kyle Jones

1
감사! 우연히 참조가 있습니까?
Ellen Spertus

1
@Aki, nope, CreateProcess ()는 문자 그대로 새로운 프로세스를 만들고 처음부터 포크하지 않고 빌드합니다.
psusi

2
그러나 유닉스 어딘가에 CreateProcess ()와 동등한 것이 없어야합니까? 그렇지 않으면 첫 번째 프로세스는 어떻게 만들어 집니까? 신화적인 창조자 신과는 달리, 첫 번째 과정은 무에서 자신을 포크 () 할 수 없습니다. ;-)
Steven 월요일

2
@StevenMonday는 가능하지만 커널의 초기화 코드에 있으며 외부에서 액세스 할 수 없습니다. 거의 모든 것이 하드 코딩되어 있기 때문에 모든 매개 변수가 필요하지 않습니다. init 프로세스라고하는 프로세스 ID 1 만 작성할 수 있습니다. 그 후에 프로세스는 분기하여 만 작성됩니다.
cjm

5

cjm의 답변과 함께 Single Unix Specification은이라는 함수를 정의합니다 vfork(). exec familly 함수를 호출하거나을 호출하는 것 이외의 다른 작업을 수행하는 경우 분기 된 프로세스에 정의되지 않은 동작이 있다는 점을 제외하면 해당 함수는 포크와 같이 작동합니다 _exit().

따라서 정의 된 동작에 대한 유일한 사용은 다음과 같습니다.

pid_t ret = vfork();
if(ret == 0)
{
    exec(...);
    _exit(EXIT_FAILURE); //in case exec failed for any reason.
}

그래서 무엇을 vfork합니까? 그것은 싸다 fork. 기록 중 복사가없는 구현에서는 결과 프로세스가 원래 프로세스와 메모리 공간을 공유하므로 정의되지 않은 동작이 발생합니다. 기록 중 복사 구현이 빠르기 때문에 기록 중 복사를 사용한 구현 vfork에서는와 동일 할 수 있습니다 fork().

새로운 프로세스를 직접 생성 할 수 있는 선택적 posix_spawn기능 (및 posix_spawnp기능)도 있습니다. (라이브러리 호출을 이용하여 이들을 구현하는 것도 허용된다 fork하고 exec, 및 구현 예들이 제공된다.)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.