스스로 fork ()와 exec ()를 언제 호출해야합니까?


9

fork () 및 exec () 명령에 대해 배우고 있습니다. fork ()와 exec ()는 보통 함께 호출되는 것 같습니다. (fork ()는 새로운 자식 프로세스를 만들고 exec ()는 현재 프로세스 이미지를 새로운 프로세스로 바꿉니다.) 그러나 어떤 시나리오에서 각 함수를 자체적으로 호출 할 수 있습니까? 이와 같은 시나리오가 있습니까?


2
전통적인 포크 폭탄 : while (1) fork (); 시스템 리소스를 비축합니다.
Joshua

답변:


22

확실한! "래퍼"프로그램의 일반적인 패턴은 다양한 작업을 수행 한 다음 exec호출 만으로 다른 프로그램으로 대체하는 것입니다 (포크 없음).

#!/bin/sh
export BLAH_API_KEY=blub
...
exec /the/thus/wrapped/program "$@"

이것의 실제 예입니다 GIT_SSH(하지만 git(1)또한 제공 않습니다 GIT_SSH_COMMAND위의 래퍼 프로그램 방식을하지 않으려는 경우).

포크 전용은 일반적으로 많은 작업자 프로세스를 생성 할 때 사용됩니다 (예 : httpd포크 모드의 Apache) (포크 전용은 네트워크 I / O가 발생할 때까지 엄지 손가락을 돌리는 프로세스가 아닌 CPU를 소모해야하는 프로세스에 적합하지만) ) 또는 OpenBSD의 다른 프로그램에 의해 사용되는 권한 분리sshd (exec 없음)

$ doas pkg_add pstree
...
$ pstree | grep sshd
 |-+= 70995 root /usr/sbin/sshd
 | \-+= 28571 root sshd: jhqdoe [priv] (sshd)
 |   \-+- 14625 jhqdoe sshd: jhqdoe@ttyp6 (sshd)

rootSSHD는 클라이언트에 자신의 복사본 (28571) 다음 권한 분리를위한 또 다른 사본 (14625) 떨어져 포크하여 연결했다.


14

많이 있습니다.

호출 fork()하지 않는 프로그램 exec()은 대개 별도의 프로세스에서 다양한 작업을 기본 프로세스 로 수행하기 위해 자식 작업자 프로세스 를 생성하는 패턴을 따릅니다 . 당신은 등 다양한 프로그램이 찾을거야 dhclient, php-fpm하고 urxvtd.

호출하는 프로그램 exec()없이이 fork()있다 연쇄 로딩 다른 프로그램의 영상과 그 프로세스를 오버레이. 상태를 처리하기 위해 특정 작업을 수행 한 다음 수정 된 프로세스 상태로 실행하기 위해 다른 프로그램을 실행하는 체인 로딩 유틸리티의 전체 하위 문화가 있습니다. 이러한 유틸리티는 daemontools 서비스 및 시스템 관리 도구 세트 에서 공통적 이지만 그로 제한되지 않습니다. 몇 가지 예 :

데몬 툴즈 가족 도구 세트는이 많이 에서 이러한 도구를 machineenv통해 find-matching-jvmruntool.


2

다른 답변 외에도을 사용하는 디버거 ptrace는 일반적으로 fork와 사이의 간격을 사용합니다 exec. PTRACE_TRACEME디버거는 자신의 상위 프로세스 (디버거)에 의해 추적되고 있음을 나타 내기 위해 자신 을 표시해야합니다. 이것은 디버거에 필요한 권한을 부여하기위한 것입니다.

따라서 디버거는 먼저 포크합니다. 아이는 전화 ptracePTRACE_TRACEME한 다음 전화를했다 exec. 자식 프로그램의 어느 프로그램이 부모에 의해 추적 될 수 있습니다.


포크와 exec 사이에 많은 일이 있으며, 가장 일반적인 것은 I / O를 재지향하는 것입니다 (예 : 파이프 설정). 그러나 문제는 전혀 exec없이 포크를하는 것에 관한 것입니다.
Barmar

0

포크없는 exec

그런 일을하고 싶은 이유는 두 가지 이상 있습니다.

  1. 체인 로딩. 현재 프로세스 이미지가 다른 것으로 바뀝니다.
  2. 현재 실행중인 프로그램을 다시 시작합니다 (예 : SIGHUP 또는 이러한 서버 프로세스, 모든 항목을 다시로드하고 완전히 새로운 시작을 수행 할 때 발생할 수 있음). 어떤면에서, 이것은 체인 로딩이라고 주장 할 수 있으며, 같은 프로그램과 우연히 만 일치합니다.

exec가없는 포크

그것이 모든 데몬이 시작될 때마다 (두 번, 실제로)하는 일입니다. 이것은 쉘이 멈추지 않고 (쉘이 대기하는 원래 프로세스가 종료되기 때문에) 쉘이 멈추지 않고 터미널이 더 이상 데몬을 제어하지 않으므로 쉘 창을 닫아도 데몬이 죽지 않습니다.

또 다른 일반적인 용도는 약 25 년 전에 아파치 웹 서버에 의해 유명해진 작업자 어린이를 포크하는 것입니다. (현재는 천둥 무리 문제가 발생하기 쉬우므로 더 이상 최첨단 기술로 간주되지 않지만 확실히 제공합니다. 가장 간단하고 가장 강력한 서버 가능).

또 다른 일반적인 용도는 일관된 스냅 샷을 만드는 것입니다. fork프로세스를 생성 할뿐만 아니라 주소 공간을 복사합니다 (이론상 실제로는 페이지를 기록 중 복사 만 표시). 이것은 (원자 적으로) 부모가 더 이상 수정할 수없는 완전한 프로그램 데이터의 스냅 샷을 만듭니다.
일부 프로그램은이를 활용합니다. 예를 들어, redis는 데이터 세트를 동시에 수정 하면서 디스크에 데이터를 일관성있는 상태로 저장 합니다. 이는 fork상위 프로세스에서 수정 한 내용을 볼 수없는 일관된 스냅 샷을 생성 했기 때문에 작동 합니다.


실제로 오늘날에는 거의 사용하지 않는데, 대부분 이것을 표준으로하지 않거나 일반적으로 사용하지 않는 모드를 가지고 있습니다. 그것은 포크에 실수 로 이어지는 준비 불일치공포 , 그리고 실수 중 하나입니다 dæmonization의 착오 . 이 실수는 오래 전부터 호의를 얻지 못했습니다.
JdeBP
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.