프로세스 생성을 위한 UNIX 시스템 호출 fork()는 상위 프로세스를 복사하여 하위 프로세스를 생성합니다. 내가 이해하기로는 거의 항상 자식 프로세스의 메모리 공간(텍스트 세그먼트 포함)을 대체하기 위해 exec()를 호출하는 것이 뒤따른다는 것입니다. fork()에서 부모의 메모리 공간을 복사하는 것은 나에게 항상 낭비적인 것처럼 보였습니다. (비록 메모리 세그먼트를 기록 중 복사(즉, 포인터만 복사됨)함으로써 낭비를 최소화할 수 있다는 것을 알고 있지만). 어쨌든 프로세스 생성에 이러한 반복적 접근 방식이 필요한 이유를 아는 사람이 있습니까?
답변1
인터페이스를 단순화하는 것입니다. fork
교체는 exec
Windows와 유사합니다.프로세스 생성기능. 얼마나 많은 매개변수가 있는지 확인하세요 CreateProcess
. 그 중 다수는 더 많은 매개변수가 있는 구조입니다. 이 때문입니다모든 것새로운 프로세스에 대한 제어권 이 CreateProcess
.CreateProcess
사용자로 프로세스 생성그리고로그인을 사용하여 프로세스 만들기.
이 fork/exec
모델에서는 이러한 매개변수가 모두 필요하지 않습니다. 대신 프로세스의 일부 속성이 에 보존됩니다 exec
. 이를 통해 fork
원하는 프로세스 속성을 변경할 수 있습니다(일반적으로 사용하는 것과 동일한 기능 사용).그 다음에 exec
. Linux에는 매개변수가 없으며 실행할 프로그램, 해당 프로그램에 제공되는 명령줄 및 환경의 3개만 fork
있습니다 . execve
(다른 함수도 있지만 일반적인 사용 사례를 단순화하기 위해 C 라이브러리에서 제공하는 래퍼 exec
일 뿐입니다 .)execve
다른 현재 디렉터리를 사용하여 프로세스를 시작하려는 경우: fork
, chdir
, exec
.
stdin/stdout: 을 리디렉션하려면 fork
파일을 닫거나 엽니다 exec
.
사용자를 전환하려면: fork
, setuid
, exec
.
이 모든 것들은 필요에 따라 결합될 수 있습니다. 누군가 새로운 프로세스 속성을 생각해낸다면 fork
및 를 변경할 필요가 없습니다 exec
.
Larsk가 언급했듯이 대부분의 최신 Unix는 쓰기 중 복사를 사용하므로 fork
관련된 오버헤드가 많지 않습니다.
답변2
cjm의 답변 외에도 Single Unix 사양에서는 vfork()
. 이 함수는 exec 함수 계열을 호출하거나 _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
있으며 예제 구현이 제공됩니다.)