2017-10-15 8 views
1

프로세스 (잭드)를 제어 할 수있는 트레이 아이콘을 구현하려고합니다. 가장 주목할만한 fork 된 자식 및 그 jackd 하위 프로세스를 파이썬에서 죽이는 방법

  • 나는

살인을 일으키는 내가 메인 프로그램의 메뉴 항목에서 프로세스를 종료 할 수 있도록하려면

  • 로깅을 위해 프로세스의 표준 출력과 표준 에러를 읽고 싶어 나 두통. 나는 stdout과 stderr를 읽을 때 추가 스레드/프로세스에서 아이콘을 응답 성있게 유지해야한다고 생각한다. 그래서 fork()를 사용하여 자식 프로세스를 만들고 자식에 setsid()을 호출했습니다. 즉, 자식 프로세스는 내가 같은 프로세스 그룹에 내 갈래의 자식 프로세스 및 jackd를 얻을 수 바라고 된 subprocess 모듈 이제

    from subprocess import PIPE, STDOUT, Popen 
    def runAndLog(self, cmd): 
        po = Popen(cmd, stdout=PIPE, stderr=STDOUT) 
        line = po.stdout.readline() 
        while line: 
         print(line.rstrip()) 
         line = po.stdout.readline() 
    self.runAndLog(["jackd","-R", "-P80", "-t5000", "-dfirewire", "-r44100", "-p256", "-n3"]) 
    

    를 사용 jackd 호출, 그래서 나는 죽일 모두 한 번에,하지만 놀랍게도 수 손자를 죽이지 않을 것이다 아이를 죽이고, 그래서

    PID PPID PGID SID COMMAND 
    5790 5788 5788 31258 python (parent, main) 
    5791 5790 5791 5791 python (forked child after setsid - ok) 
    5804 5791 5804 5804 jackd (grandchild created by Popen) 
    

    난에 main에 알려진 손자의 PID (5804)를 만들기의 깨끗한 방법을 볼 수 없습니다 : Popen는 새로운 프로세스 그룹과 새로운 세션을 생성 명시 적으로 그것을 죽이기 위해서. 죽어가는 자식이 손자를 죽이게하는 데 쓸모있는 신호를 사용할 수는 있습니다.하지만 저는이 일을 망설입니다.

    또한 SID가 내 자녀의 SID와 다르므로 jackd 프로세스에서 자식 프로세스 그룹으로 강제로 적용 할 수 없습니다. setpgid

    나는 나도

    • 새로운 세션을 생성하지는 popen을 설득 할 생각, 또는
    • subprocess보다 적은 마법 모듈을 사용하지만, 여전히 표준 출력과 표준 에러를 읽고 나를 alows있다.

    하지만 어떻게해야할지 모르겠다. 프로세스 그룹에 대한 내 지식은 다소 제한적입니다.

    /home/martin >python --version 
    Python 2.7.1 
    

    업데이트 10월 12일

    나는 새로운 세션이 파이썬에 의해 생성되지 않는다는 것을 발견하지만 jackd 자체. 잭을 xterm으로 대체하면 모든 것이 정상입니다.

    PID PPID PGID SID COMMAND 
    12239 4024 12239 4024 python (parent, main) 
    12244 12239 12244 12244 python (forked child after setsid - ok) 
    12249 12244 12244 12244 xterm (grandchild has same PGID and SID - ok) 
    

    는 또한 this

    이 잭 일 호출을 발견 setsid() 자체는

    에 옵션을 잎 새로운 프로세스 그룹 리더

    으로 설립하려면

    • 잭의 PID를에 알리기 (210) 및 jackd

    그에 대한 조언 죽이고 죽이고 명시 적으로 죽일, 또는

  • 는 죽어가는 아이를?

    .

  • +0

    이 답변이 도움이됩니까? http://stackoverflow.com/a/4791612 –

    +0

    그게 내가하는 일이야. 그러나, 나는 그 문제가 정말로 jackd 자체이고 python이 아니라는 것을 발견했다. 그에 따라 내 질문을 업데이트하겠습니다. –

    +0

    그냥 스레드를 사용하고'jack '을 직접 제어하지 않는 이유는 무엇입니까? 실제 커맨드를 제어하기 위해 별도의 하위 프로세스를 만드는 이유는 무엇입니까? 그것을 훨씬 더 복잡하게 만드는 것으로 추정되는 이점은 무엇입니까? –

    답변

    1

    귀하의 손자가 자신의 세션과 sid를 설정 했으므로 group-kill이 제대로 작동한다고 기대할 수 없습니다. 당신은 세 가지 옵션이 있습니다 어린이 프로세스의 전체 트리를 통해

    1. 반복 처리를하고, (그들은 아이를 다시 시작하지 않을 수 있도록) 모든 부모로부터 시작하여 그들을 죽일. 추악하고 복잡해진 솔루션.

    2. 메인 (루트) 프로세스의 스레드를 사용하여 jack 하위를 직접 제어하십시오. 중간의 하위 프로세스는 아무런 이점도 없으므로 아마도 여기에 필요하지 않습니다. 이것은 가능한 가장 간단한 솔루션입니다.

    child.py :

    import signal 
    import subprocess 
    
    # The signal handler for the child process, which passes it further to the grandchild. 
    def handler(signum, frame): 
        print('Killing self, killing the children') 
    
        os.kill(proc.pid, signal.SIGTERM) 
    
        # wait for the process to die gracefully for N secs. 
        time.sleep(5) 
    
        os.kill(proc.pid, signal.SIGKILL) 
    
    cmd = ["jackd","-R", "-P80", "-t5000", "-dfirewire", "-r44100", "-p256", "-n3"] 
    po = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 
    
    signal.signal(signal.SIGTERM, handler) 
    
    for line in po.stdout: 
        print(line.rstrip()) 
    
  • 여전히 중간 자식 프로세스를 가지고있는 경우

    는 유일한 방법은 아이에게 전송 종료 신호를 잡아, 그리고 손자로 전송하는

    신호 처리기는 프로세스 통신이 시작되기 전에 설치됩니다 (라인 읽기).

    루트 프로세스가 자식 프로세스를 "정상적으로"(예 : SIGTERM으로) 죽일 때마다 신호가 손자에게 전달되어 종료/종료됩니다. 죽이기와 기다리기, 그리고 강제로 죽이는 논리를 확장 할 수도 있습니다.

    그러나 자식 프로세스가 SIGKILL로 종료되면이 신호를 잡을 기회가없고 손자도 고아가 계속 실행됩니다. SIGKILL은 설계 상 잡을 수 없기 때문에.