POSIX에서 프로세스는 두 가지 기본 계층을 통해 서로 "관련"됩니다.
상위 및 하위 프로세스의 계층 구조입니다.
세션 및 프로세스 그룹의 계층 구조.
setpgid
setsid
사용자 프로세스는 후자 , via 및 Beyond를 통해 변경되지 않는 많은 제어 기능을 갖습니다 . 돌이켜보면 부모와 자식의 관계가 얼마나 중요한지 늘 궁금합니다.
지금까지 제가 이해한 내용을 요약하면 다음과 같습니다.
아이의 입장에서 보면 부모-자녀 관계는 당연히 중요합니다.부모다양한 시스템 호출(예:
wait
및setpgid
)은 하위 프로세스에서만 허용되기 때문입니다.세션-그룹-프로세스 관계는 다음과 같습니다.모두
kill
전체 프로세스 그룹에 대한 작업과 같은 시스템 호출은setpgid
동일한 세션의 그룹에 참여하는 데만 사용할 수 있고SIGHUP
세션 리더가 세션의 모든 프로세스로 전송되는 경우 세션 리더 이든 세션의 다른 프로세스이든 상관없습니다. 세션 포그라운드 프로세스 그룹 프로세스가 종료됩니다.게다가 상위 프로세스의 관점에서 볼 때 두 계층은 분명히 관련되어 있습니다. 왜냐하면
setsid
새 하위 프로세스에만 영향을 주고setpgid
하위 프로세스에서만 사용할 수 있기 때문입니다. 그러나 하위 프로세스의 관점에서는 본질적으로 관련이 없는 것처럼 보입니다. 상위 프로세스의 종료는 프로세스의 그룹이나 세션에 영향을 미치지 않습니다.
그러나 자식 프로세스가 현재 부모가 무엇인지 신경 쓸 이유가 전혀 없습니다. 그래서 다음과 같은 질문이 있습니다.getppid()
현재 값이 하위 프로세스의 관점에서 어떤 의미를 갖나요?, 빌드 프로세스가 종료되었는지 확인하는 것 외에도?
동일한 질문을 다른 방식으로 물어보려면 동일한 프로그램이 두 가지 다른 방식으로 동일한 상위 프로그램에서 두 번 생성되었다고 상상해 보세요.
첫 번째 아이는 평소대로 태어났고,
fork()
곧바로 이어졌습니다exec()
.두 번째 하위 프로세스는 간접적으로 생성됩니다. 상위 프로세스가 을 호출한
fork()
다음 하위 프로세스가 호출됩니다.반품전화해fork()
, 그렇지손자호출 프로세스exec()
. 그런 다음 직계 자식이 종료되므로 손자는 고아가 되고 해당 PPID는 PID 1로 다시 할당됩니다.
이 가상 시나리오에서 다른 모든 것이 동일하다고 가정하면 합리적인 프로그램이 다르게 동작할 이유가 있습니까?지금까지 내 결론은 "아니요"인 것 같습니다. 프로세스에서 상속된 파일 설명자와 마찬가지로 세션이 변경되지 않은 상태로 유지되기 때문입니다. 그러나 확실하지 않습니다.
참고: "통신할 상위 PID 가져오기"는 이 질문에 대한 유효한 답변이라고 생각하지 않습니다. 왜냐하면 고아 프로세스는 일반적으로 PPID를 1로 설정할 수 없기 때문입니다(일부 시스템은 고아 프로세스의 PPID를 다른 값으로 설정함). ), 따라서 경쟁 조건을 피하는 유일한 방법은 다음을 호출하여 상위 프로세스 ID를 얻는 것입니다.getpid()
앞으로포크한 다음 하위 항목에서 해당 값을 사용합니다.
답변1
이 질문을 보고 관심이 생겼습니다.알다전에 getppid가 사용된 것을 본 적이 있는데.. 어디서 사용했는지 기억이 나지 않습니다. 그래서 저는 모든 Linux 시스템 호출을 사용할 수 있을 것으로 생각되는 프로젝트에 관심을 돌렸고 다음 중 일부는 다음과 같습니다.체계. 하나GitHub 검색나중에 좀 더 일반적인 사용 사례를 설명하는 두 가지 용도를 발견했습니다(다른 용도도 있지만 systemd에 더 구체적입니다).
존재하다SD 알림. 일부 상황에서: systemd는 서비스가 시작되는 시기를 알아야 해당 서비스에 의존하는 모든 서비스를 시작할 수 있습니다. 이는 일반적으로 C 프로그램을 통해 수행됩니다.sd_알림 API, 이는 데몬이 systemd에게 상태를 알려주는 방법입니다.
물론 셸 스크립트를 서비스로 사용하는 경우 C 함수를 호출하는 것이 완전히 가능하지는 않습니다. 따라서 systemd는 다음과 같이 제공됩니다.시스템 알림 명령, sd_notify API에 대한 작은 래퍼입니다. 문제 1: systemd는 전송되는 메시지의 PID도 알아야 합니다. systemd-notify의 경우 이는 자체 PID가 되며 즉시 사라지는 단기 프로세스 ID가 됩니다. 쓸모 없는.
아마도 여러분은 이미 내가 무엇을 할지 알고 있을 것입니다. systemd-notify는 getppid를 사용하여 상위 프로세스의 PID를 가져옵니다. 이는 일반적으로 실제 서비스 프로세스이기 때문입니다. 즉, 수명이 짧은 CLI 애플리케이션은 getppid를 사용하여 상위 프로세스를 대신하여 메시지를 보낼 수 있습니다.
이것을 발견했을 때 나는 getppid를 사용할 수 있는 또 다른 Unix 도구인 polkit을 생각했습니다. 이는 D-Bus 메시지 전송이나 권한 있는 응용 프로그램 실행과 같은 작업을 제어하는 데 사용되는 프로세스 인증 프레임워크입니다. (적어도 polkit의 인증 에이전트가 표시하는 GUI 비밀번호 프롬프트를 본 것 같습니다.) polkit에는 sudo라는 실행 파일이 포함되어 있습니다.
pkexec
이는 sudo와 다소 유사하게 사용되지만 현재는 polkit이 인증에 사용됩니다. 이제 polkit은 승인을 요청하는 프로세스의 PID를 알아야 합니다. 예, 알겠습니다.pkexec는 getppid를 사용하여 다음을 찾습니다..(저도 시청하면서 발견했습니다.polkit의 TTY 인증 프록시에서도 사용됩니다..)
이것은 조금 덜 흥미롭지만 여전히 주목할 가치가 있습니다. getppid는 다음 용도로 사용됩니다.PR_SET_PDEATHSIG 시뮬레이션이 플래그가 설정된 경우 부모가 사망한 경우입니다. (이 플래그는 상위 프로세스가 종료될 때 SIGKILL과 같은 신호를 하위 프로세스에 자동으로 보내는 방법일 뿐입니다.)
답변2
좀비: 이는 극단적인 경우이지만 프로그램 중지 여부에 영향을 미친다는 점에서 유효합니다. 자식 프로세스가 부모에 따라 다르게 동작하는 유일한 상황은 종료될 때입니다. 프로세스가 종료되면 자식 프로세스 SIGCHLD
로 전송됩니다 . ppid
상위 프로세스가 고정되거나 처리되지 않은 채로 남겨지면 SIGCHLD
하위 프로세스는 종료 신호가 수신될 때까지 좀비 상태에 있게 됩니다. ppid
좀비 상태에서 자식 프로세스가 변경되면 부모 프로세스를 종료하고 부모 프로세스를 재설정하여 수신 init
하면 SIGCHLD
자식 프로세스가 종료를 완료하고 수확됩니다.
답변3
프로세스가 시스템의 다른 프로세스(예: 상위 프로세스, 상위 프로세스 등)에 대해 알아야 하는 시나리오의 범위에는 프로세스 관리 및/또는 프로세스 간 통신이 포함되는 것으로 보입니다. 범위를 더 좁히기 위해 pid_t
a를 매개변수로 사용하거나 a를 반환하는 작업의 범위는 pid_t
주로 신호 및 기타 프로세스 관리 작업입니다. 이러한 제한된 사용 범위를 고려할 때 진단 정보 외에 제가 생각할 수 있는 유일한 이유는 getppid
자식이 부모에게 신호를 보내야 하는지 또는 부모가 여전히 실행 중인지 확인해야 하는 경우입니다. 예를 들어, mod_md
아파치에서는httpd
상위 프로세스에 정상적인 재시작 신호 보내기트리거 재구성.
귀하의 질문에 있는 "주석"은 에 대한 좋은 대안을 설명하지만 getppid
에 대한 가능한 용도를 암시하는 것 같습니다 getppid
. 배경으로 어젯밤 PWL Conf 2019 프레젠테이션을 보았는데,프로그래밍 언어의 표현력에 대하여, 그리고 논문의 "표현성"에 대한 정의는 이 문제에 대한 나의 해석을 편향시켰습니다. 정의는 특정 기능의 유무에 따라 프로그램의 동작이 달라질 수 있다는 사실로 요약됩니다.
가설로 시작하세요:
- 어떤 이유로 프로세스는 상위 프로세스에 신호를 보내야 합니다.
- 운영 체제마다 고아 프로세스의 부모 재지정을 다르게 처리합니다.
fork
사전 PID가 일치하지 않으면 무엇을 의미합니까 getppid
? fork
사전 PID와의 비교는 getppid
실제로 자식 프로세스가 고아인지 여부를 확인하기 위한 크로스 플랫폼, 경합 없는 메커니즘을 제공할 수 있습니다. 그렇다면 pre-fork-pid != getppid
그 아이는 고아이고, 그렇지 않으면 그렇지 않습니다.
이는 흔하지 않은 요구 사항이거나 #ifdef
필요한 경우 플랫폼별 컴파일을 사용하여 작성할 수 있는 것으로 보입니다. 또한 kill 0
pre- 를 사용하여 fork
유사한 효과를 얻을 수 있지만 pid
시스템이 "이전" 프로세스 ID를 재사용할 때 충분히 오랫동안 실행된 프로세스에서 오탐지가 발생할 수 있습니다.
fork
따라서 불변의 사전 상위 프로세스 ID와 "실시간" 호출의 조합은 getppid
신호를 확인하거나 상위 프로세스로 보내는 데 매우 안정적인 크로스 플랫폼 메커니즘이 될 수 있는 것처럼 보입니다.