2014-07-22 2 views
4

로컬 JBoss 인스턴스를 시작하는 스크립트를 작성할 때 이상한 문제가 발생했습니다.KeyboardInterrupt에서 일련의 하위 프로세스를 종료합니다.

with open("/var/run/jboss/jboss.pid", "wb") as f: 
    process = subprocess.Popen(["/opt/jboss/bin/standalone.sh", "-b=0.0.0.0"]) 
    f.write(str(process.pid)) 

    try: 
     process.wait() 
    except KeyboardInterrupt: 
     process.kill() 

는 이해하기 매우 간단 나는 KeyboardInterrupt를 일단의 실행, 자식 프로세스를 종료하면서 파일에 PID를 작성해야 :

내 코드는 다음과 같이 보입니다.

신호가 standalone.sh에 의해 시작된 Java 프로세스로 전파되지 않는 것처럼 보이기 때문에, kill 신호를 보낸 후에 JBoss가 백그라운드에서 계속 실행되는 것이 문제입니다.

나는 시스템 관리 스크립트를 작성하기 위해 파이썬을 사용한다는 생각을 좋아하지만, 배시에서 작성한다면 모든 것이 제대로 작동했을 것입니다.

KeyboardInterrupt을 얻을 때 어떻게 전체 프로세스 트리를 죽일 수 있습니까? 지금까지 내가 subprocess 모듈은 서브 프로세스에 의해 산란 아이들을 검색 할 수있는 API 기능을 제공하지 않습니다 알고

import psutil 

#.. 

proc = psutil.Process(process.pid) 
for child in proc.children(recursive=True): 
    child.kill() 

proc.kill() 

을, 나 os 모듈을 수행합니다

답변

3

당신은 psutil 라이브러리를 사용하여이 작업을 수행 할 수 있습니다. 프로세스를 죽이는


더 좋은 방법은 아마도 다음과 같습니다

proc = psutil.Process(process.pid) 
procs = proc.children(recursive=True) 
procs.append(proc) 

for proc in procs: 
    proc.terminate() 

gone, alive = psutil.wait_procs(procs, timeout=1) 
for p in alive: 
    p.kill() 

이 올바르게 종료하고 제한 시간이 종료되면 남아있는 프로세스가 살해 될 프로세스에 기회를 줄 것이다. psutilpsutil.Processsubprocess.Popen플러스 모든 추가 기능의 동일한 인터페이스를 가지고 Popen 클래스를 제공하는


참고. subprocess.Popen 대신 간단히 사용하는 것이 좋습니다. psutilsubprocess은 프로세스가 종료 될 때 PID가 재사용되지 않는다고 확인하기 때문에 안전 문자이기도합니다.

관련 문제