fork()와 exec()는 언제 별도로 호출됩니까?

fork()와 exec()는 언제 별도로 호출됩니까?

나는 배우고 fork()명령 exec()하고 있습니다. 외모 fork()exec()일반적으로 함께 호출됩니다. ( fork()새 하위 프로세스를 생성하고 exec()현재 프로세스 이미지를 새 프로세스 이미지로 바꿉니다.) 그러나 어떤 상황에서 각 함수를 개별적으로 호출할 수 있습니까? 그런 시나리오가 있나요?

답변1

틀림없이! "래퍼" 프로그램의 일반적인 패턴은 다양한 작업을 수행한 다음 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를 소비해야 하는 프로세스에 더 적합하지만)) 또는 ~을 위한특권의 분리sshdOpenBSD의 프로그램 및 기타 프로그램에서 사용됨(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)

sshd는 root클라이언트 연결(28571)에서 자체 복사본을 포크한 다음 권한 분리를 위해 다른 복사본(14625)을 포크합니다.

답변2

많이있다.

fork()호출하지 않는 프로그램은 exec()일반적으로 하위 프로세스를 생성하는 패턴을 따릅니다.작업 과정메인 프로세스와 다른 프로세스에서 다양한 작업을 수행하는데 사용됩니다. dhclient, , 및 와 php-fpm같은 다양한 프로그램에서 이를 찾을 수 있습니다 urxvtd.

exec()호출하지 않는 프로그램 fork()체인 로딩, 다른 프로그램 이미지로 프로세스를 덮어씁니다. 처리 상태에 대해 특정 작업을 수행한 다음 수정된 프로세스 상태로 실행하기 위해 다른 프로그램을 실행하는 체인 로딩 유틸리티의 전체 하위 문화가 있습니다. 이러한 유틸리티는 일반적으로 다음에서 찾을 수 있습니다.데몬 도구 계열서비스 및 시스템 관리 도구 세트(이에 국한되지 않음) 몇 가지 예를 들면 다음과 같습니다.

daemontools 도구 세트 시리즈에는 다음이 포함됩니다.많은이러한 도구는 다음에서 제공됩니다.machineenv통과하다find-matching-jvm도착하다runtool.

답변3

다른 답변 외에도 디버거는 ptrace종종 forkexec. 디버그 개체는 PTRACE_TRACEME상위 프로세스(디버거)에 의해 추적되고 있음을 나타내기 위해 자체적으로 표시하는 데 사용되어야 합니다. 이는 디버거에 필요한 권한을 부여하기 위한 것입니다.

따라서 디버거가 먼저 포크됩니다. 아이가 ptrace먼저 전화를 PTRACE_TRACEME한 다음 전화를 겁니다 exec. 이제 하위 실행자에 있는 프로그램을 상위 실행자가 추적할 수 있습니다.

답변4

포크 없이 실행

이와 같은 작업을 수행하려는 데에는 최소한 두 가지 이유가 있습니다.

  1. 체인 로딩. 현재 프로세스 이미지가 다른 이미지로 대체됩니다.
  2. 현재 실행 중인 프로그램을 다시 시작합니다. 예를 들어 SIGHUP이나 서버 프로세스를 모두 다시 로드하고 클린 부팅을 수행할 때 이런 일이 발생할 수 있습니다. 어느 정도는 이것이 체인 로딩이고 동일한 프로그램과의 우연의 일치라고 생각할 수도 있습니다.

exec가 없는 포크

이는 각 데몬이 시작될 때마다(실제로 두 번) 수행하는 작업입니다. 이는 쉘이 정지되지 않고(쉘이 종료되기를 기다리고 있던 원래 프로세스가 종료되기 때문에) 데몬이 더 이상 터미널 제어 하에 있지 않으므로 쉘 창을 닫아도 데몬이 종료되지 않는 등 여러 가지 작업을 수행합니다.

또 다른 일반적인 용도는 약 25년 전에 Apache 웹 서버로 유명해진 작업자 자식을 포크하는 것입니다(현재는 천둥 떼 문제에 대한 취약성으로 인해 더 이상 최첨단 기술로 간주되지 않지만 다음을 제공합니다). 가능한 가장 간단하고 가장 강력한 서버입니다).

또 다른 일반적인 용도는 일관된 스냅샷을 생성하는 것입니다. fork프로세스를 생성할 뿐만 아니라 주소 공간도 복사합니다(이론적으로는 실제로 페이지 쓰기 시 복사만 표시함). 이는 상위 프로그램이 더 이상 수정할 수 없는 전체 프로그램 데이터의 스냅샷을 (원자적으로) 생성합니다.
일부 프로그램은 이를 활용합니다. 예를 들어 redis는 데이터를 디스크에 (일관된 상태로) 저장하는 반면개정하다데이터 세트는 동시에 실행됩니다. 이는 fork일관된 스냅샷이 생성되고 상위 프로세스의 수정 사항이 표시되지 않기 때문에 작동합니다 .

관련 정보