2017-02-10 1 views
4

waitFor을 사용하지 않으면 JVM을 종료해도 하위 프로세스에는 영향을 미치지 않습니다. 다음은 그 예입니다.waitFor를 사용하면 JVM을 종료해도 자식 프로세스가 종료되는 이유는 무엇입니까?

배쉬 스크립트 :

#!/usr/bin/env bash 
echo "Sleeping..." > 'log' 
sleep 30 
echo "Wake up" >> 'log' 

자바 코드 : Java Code 발행

public class Code { 
    public static void main(String[] args) throws Exception { 
    Process process = Runtime.getRuntime().exec("./child.sh"); 
    // process.waitFor(); 
    } 
} 

후에는, JVM은 즉시 종료됩니다. 그리고 ps -ef | grep 'child.sh' | grep -v grep 보여줍니다 :

jing  3535 2761 0 13:47 pts/15 00:00:00 bash ./child.sh 

그런 다음 30 초 후에, 나는 현재 디렉토리에 log 파일의 내용을 확인합니다. 내용은 다음과 같습니다.

Sleeping... 
Wake up 

위의 grep 명령에는 아무 것도 표시되지 않습니다. 이제 process.waitFor()을 주석 처리하고 Code.java을 다시 컴파일하십시오. java Code을 실행 한 후 위의 grep 명령을 사용하여 child.sh 자식 프로세스가 실행 중인지 확인합니다. 그런 다음 Ctrl-C을 발행하면 JVM이 종료됩니다. 위의 grep 명령을 실행하면 아무 것도 표시되지 않습니다. 나는이 행동을 설명하지 않습니다 Process의 자바 독을 점검 한

Sleeping... 

:로 그리고 log 파일의 내용은 유지됩니다. 그런 다음 다음 코드를 사용하여 fork, execlpwaitpid 시스템 호출의 동작을 확인합니다. 그리고 그것은 같은 행동을 보여줍니다.

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <sys/wait.h> 

static void err_sys(const char* msg) { 
    printf("%s\n", msg); 
    exit(1); 
} 

int main(void) { 
    pid_t pid; 

    if ((pid = fork()) < 0) { 
     err_sys("fork error"); 
    } else if (pid == 0) { 
     if (execlp("/home/jing/code/lintcode/child.sh", "child.sh", (char *)0) < 0) 
      err_sys("execlp error"); 
    } 

    if (waitpid(pid, NULL, 0) < 0) 
    err_sys("wait error"); 

    exit(0); 
} 

저는 Oracle JDK 1.8을 Ubuntu 14.04에서 사용하고 있습니다. uname -a는 생산 :

Linux jinglin 3.13.0-108-generiC#155-Ubuntu SMP Wed Jan 11 16:58:52 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux 

사람은 waitForwaitpid의 효과에 대한 설명을 줄 수 있습니까?

Does Process.waitFor() make the process reliant on the java parent?은 MAC 플랫폼에서 비슷한 문제를 묻습니다. 그러나 세부 사항은 부족합니다. 그래서 나는이 환경에 대해이 질문을한다.

답변

3

부모 프로세스를 포 그라운드로 유지하는 것 외에도 waitPid()에는 특별한 것이 없습니다.


당신이 포크와 아이가 끝날 때까지 기다립니다 경우이 같은 (간체) 프로세스 트리가 :

─┬= 1 init 
└─┬= 2 bash --login 
    └─┬= 3 java code 
    └─── 4 bash child.sh 

java 터미널의 전경 과정과 아이에 그 프로세스 그룹.

^C를 누르면 전체 전경 프로세스 그룹 이 종료됩니다.. 당신이하지 대기 할 경우 1


후 처음 프로세스 트리 위의 것과 동일합니다.java 프로세스가 종료되고 하위 프로세스가 프로세스 트리의 루트에있는 프로세스의 하위 프로세스가됩니다.

─┬= 1 init 
├──= 2 bash --login 
└─── 4 bash child.sh 

자식 프로세스가 실행을 끝내고 정상적으로 종료됩니다.


1 프로세스 그룹

기본 액션이 종료 인 해당하는 SIGINT를 수신한다. 그러나 다른 신호 처리기가 설치 될 수 있습니다.

+0

정말인가요? 제어 터미널은 관련된 세 프로세스 모두에서 동일하며 닫히지 않습니다. –

+0

참. 그런데 어떻게 끝내나요? – Ingo

+0

커널은 터미널의 세션의 포 그라운드 프로세스 그룹에 SIGINT를 보냅니다. –

관련 문제