VirtualBox를 사용하여 Windows 8.1에서 Ubuntu 14.04 LTS를 실행하고 있습니다. 운영 체제에 접근 중인데 다음 프로그램에서 이상한 결과가 표시됩니다.
#include <stdio.h>
#include <unistd.h>
int main() {
printf("I'm the parent, my PID is %d, my parent is process %d\n",
getpid(), getppid());
fork();
printf("This sentence has been printed by process: %d my parent is process %d\n",
getpid(), getppid());
return 0;
}
GCC로 컴파일하고 실행했습니다. 그러면 출력은 다음과 같습니다.
kocks@kocks-VirtualBox:~$ ./uno
I'm the parent, my PID is 3746, my parent is process 3507
This sentence has been printed by process: 3746 my parent is process 3507
kocks@kocks-VirtualBox:~$ This sentence has been printed by process: 3747 my parent is process 2857
문제는 세 번째 문장에 있습니다. 저는 "부모 프로세스가 3746입니다"라고 예상했습니다. 특히 숫자(2857)는 항상 동일하며 VM을 다시 시작한 후에만 변경됩니다. 추가할 몇 가지 사항이 있습니다.
wait()
반환 전에 추가 하면 완벽하게 작동합니다.- 가상 머신을 "포주"하려고 하면(예: 프로세서 2개, 메모리 추가 등) 가끔 무작위로 올바른 출력이 반환됩니다.
그럼 문제는 가상머신에 있는 것 같은데요, 그렇죠? 이 문제를 어떻게 해결할 수 있나요?
편집하다 이중 부팅으로 Ubuntu에서 프로그램을 실행할 때 출력은 다음과 같습니다.
I'm the parent, my PID is 3186, my parent is process 2454
This sentence has been printed by process: 3186 my parent is process 2454
This sentence has been printed by process: 3187 my parent is process 3186
어떻게 이럴 수있어?
답변1
저는 OS X를 호스트로 사용하고 클라이언트당 1개의 CPU만 할당하는 2개의 가상 머신 설정에서 테스트했습니다.
1 우분투 14.04.2
이 설정에서는 X Window 환경에서 동작이 OP의 동작과 일치합니다.
john@U64D:~$ ./a
I'm the parent, my PID is 2682, my parent is process 2632
This sentence has been printed by process: 2682 my parent is process 2632
john@U64D:~$ This sentence has been printed by process: 2683 my parent is process 1673
상위 프로세스 1673은 로그아웃했다가 다시 로그인할 때까지 동일하게 유지됩니다.
john@U64D:~$ ./a
I'm the parent, my PID is 3787, my parent is process 3740
This sentence has been printed by process: 3787 my parent is process 3740
john@U64D:~$ This sentence has been printed by process: 3788 my parent is process 3107
./a
I'm the parent, my PID is 3790, my parent is process 3740
This sentence has been printed by process: 3790 my parent is process 3740
john@U64D:~$ This sentence has been printed by process: 3791 my parent is process 3107
3107 화초기화--사용자
john@U64D:~$ ps -ef|grep 3107
john 3107 2911 0 15:07 ? 00:00:00 init --user
그러나 X가 아닌 환경(예: tty1)에서는 결과가 Barmar의 답변과 일치합니다.
2 데비안 7.8
이 설정은 X 환경과 X가 아닌 환경 모두에 대한 Barmar의 답변과 일치합니다.
존@데비안:~$ ./a
I'm the parent, my PID is 3455, my parent is process 3406
This sentence has been printed by process: 3455 my parent is process 3406
john@debian:~$ This sentence has been printed by process: 3456 my parent is process 1
결론적으로
OP 관찰은 기본 X 환경에서 세션 초기화를 사용하는 Ubuntu의 결과입니다. 세션 초기화 세부정보를 확인할 수 있습니다.여기.
답변2
사용하지 않으면 wait()
자녀가 달리기 전에 부모가 끝낼 수 있습니다. 자식 프로세스가 호출하면 getppid()
부모 프로세스는 이미 종료되었으므로 자식 프로세스가 채택됩니다 init
. 일반적인 Unix 구현에서 PID는 init
1이므로 다음과 같이 예상할 수 있습니다.우리 부모님은 프로세스 1이세요이런 일이 발생하면. 그러나 분명히 VirtualBox가 이것을 변경했습니다.
를 사용하면 wait()
종료하기 전에 부모가 자식이 완료될 때까지 기다리게 됩니다. 이렇게 하면 그 아이는 결코 고아가 되지 않을 것입니다.