복붙노트

[PYTHON] 한 시간 내에 끝나지 않으면 프로세스를 실행하고 종료합니다.

PYTHON

한 시간 내에 끝나지 않으면 프로세스를 실행하고 종료합니다.

나는 파이썬에서 다음을 할 필요가있다. 프로세스 (하위 프로세스 모듈)를 생성하고 싶습니다.

이것을 달성하는 가장 우아한 방법은 무엇입니까?

해결법

  1. ==============================

    1.하위 프로세스 모듈이 친구가됩니다. 프로세스를 시작하여 Popen 객체를 얻은 다음 Popen 객체를 이와 같은 함수에 전달합니다. 타임 아웃시에만 예외가 발생합니다. 원하는 경우 예외를 catch하고 Popen 프로세스에서 kill () 메서드를 호출 할 수 있습니다. (kill은 Python 2.6, btw에서 새로운 것입니다)

    하위 프로세스 모듈이 친구가됩니다. 프로세스를 시작하여 Popen 객체를 얻은 다음 Popen 객체를 이와 같은 함수에 전달합니다. 타임 아웃시에만 예외가 발생합니다. 원하는 경우 예외를 catch하고 Popen 프로세스에서 kill () 메서드를 호출 할 수 있습니다. (kill은 Python 2.6, btw에서 새로운 것입니다)

    import time
    
    def wait_timeout(proc, seconds):
        """Wait for a process to finish, or raise exception after timeout"""
        start = time.time()
        end = start + seconds
        interval = min(seconds / 1000.0, .25)
    
        while True:
            result = proc.poll()
            if result is not None:
                return result
            if time.time() >= end:
                raise RuntimeError("Process timed out")
            time.sleep(interval)
    
  2. ==============================

    2.psutil을 사용하여 프로세스 PID를 알고있는 한 적어도 두 가지 방법이 있습니다. 프로세스가 다음과 같이 생성된다고 가정합니다.

    psutil을 사용하여 프로세스 PID를 알고있는 한 적어도 두 가지 방법이 있습니다. 프로세스가 다음과 같이 생성된다고 가정합니다.

    import subprocess
    subp = subprocess.Popen(['progname'])
    

    ... 다음과 같이 바쁜 루프에서 생성 시간을 얻을 수 있습니다.

    import psutil, time
    
    TIMEOUT = 60 * 60  # 1 hour
    
    p = psutil.Process(subp.pid)
    while 1:
        if (time.time() - p.create_time) > TIMEOUT:
            p.kill()
            raise RuntimeError('timeout')
        time.sleep(5)
    

    ... 또는 간단하게, 당신은 이것을 할 수 있습니다 :

    import psutil
    
    p = psutil.Process(subp.pid)
    try
        p.wait(timeout=60*60)
    except psutil.TimeoutExpired:
        p.kill()
        raise
    

    또한, 다음과 같은 추가 API에 관심이있을 것입니다.

    >>> p.status()
    'running'
    >>> p.is_running()
    True
    >>>
    
  3. ==============================

    3.나는 비슷한 질문을했고이 대답을 발견했다. 완전성을 위해 주어진 시간이 지난 후에 hanging 프로세스를 종료하는 방법을 하나 더 추가하겠습니다 : python signal library https://docs.python.org/2/library/signal.html

    나는 비슷한 질문을했고이 대답을 발견했다. 완전성을 위해 주어진 시간이 지난 후에 hanging 프로세스를 종료하는 방법을 하나 더 추가하겠습니다 : python signal library https://docs.python.org/2/library/signal.html

    문서에서 :

    import signal, os
    
    def handler(signum, frame):
        print 'Signal handler called with signal', signum
        raise IOError("Couldn't open device!")
    
    # Set the signal handler and a 5-second alarm
    signal.signal(signal.SIGALRM, handler)
    signal.alarm(5)
    
    # This open() may hang indefinitely
    fd = os.open('/dev/ttyS0', os.O_RDWR)
    
    signal.alarm(0)          # Disable the alarm
    

    어쨌든 새 프로세스를 생성하려고 했으므로 문제에 대한 최선의 해결책이 아닐 수도 있습니다.

  4. ==============================

    4.멋지고 수동적 인 방법은 threading.Timer를 사용하고 콜백 함수를 설정하는 것입니다.

    멋지고 수동적 인 방법은 threading.Timer를 사용하고 콜백 함수를 설정하는 것입니다.

    from threading import Timer
    
    # execute the command
    p = subprocess.Popen(command)
    
    # save the proc object - either if you make this onto class (like the example), or 'p' can be global
    self.p == p
    
    # config and init timer
    # kill_proc is a callback function which can also be added onto class or simply a global
    t = Timer(seconds, self.kill_proc)
    
    # start timer
    t.start()
    
    # wait for the test process to return
    rcode = p.wait()
    
    t.cancel()
    

    프로세스가 제때에 끝나면 wait ()가 끝나고 여기에서 코드가 계속됩니다. cancel ()은 타이머를 중지합니다. 한편 타이머가 만료되어 별도의 스레드에서 kill_proc을 실행하면 wait ()도 여기에서 계속되고 cancel ()은 아무 것도하지 않습니다. rcode 값으로 우리가 시간 초과되었는지 여부를 알 수 있습니다. 가장 간단한 kill_proc : (당연히 그 밖의 어떤 것도 할 수 있습니다)

    def kill_proc(self):
        os.kill(self.p, signal.SIGTERM)
    
  5. from https://stackoverflow.com/questions/1359383/run-a-process-and-kill-it-if-it-doesnt-end-within-one-hour by cc-by-sa and MIT license