Using module 'subprocess' with timeout

后端 未结 29 2495
旧巷少年郎
旧巷少年郎 2020-11-21 15:15

Here\'s the Python code to run an arbitrary command returning its stdout data, or raise an exception on non-zero exit codes:

proc = subprocess.P         


        
29条回答
  •  悲&欢浪女
    2020-11-21 16:15

    I had the problem that I wanted to terminate a multithreading subprocess if it took longer than a given timeout length. I wanted to set a timeout in Popen(), but it did not work. Then, I realized that Popen().wait() is equal to call() and so I had the idea to set a timeout within the .wait(timeout=xxx) method, which finally worked. Thus, I solved it this way:

    import os
    import sys
    import signal
    import subprocess
    from multiprocessing import Pool
    
    cores_for_parallelization = 4
    timeout_time = 15  # seconds
    
    def main():
        jobs = [...YOUR_JOB_LIST...]
        with Pool(cores_for_parallelization) as p:
            p.map(run_parallel_jobs, jobs)
    
    def run_parallel_jobs(args):
        # Define the arguments including the paths
        initial_terminal_command = 'C:\\Python34\\python.exe'  # Python executable
        function_to_start = 'C:\\temp\\xyz.py'  # The multithreading script
        final_list = [initial_terminal_command, function_to_start]
        final_list.extend(args)
    
        # Start the subprocess and determine the process PID
        subp = subprocess.Popen(final_list)  # starts the process
        pid = subp.pid
    
        # Wait until the return code returns from the function by considering the timeout. 
        # If not, terminate the process.
        try:
            returncode = subp.wait(timeout=timeout_time)  # should be zero if accomplished
        except subprocess.TimeoutExpired:
            # Distinguish between Linux and Windows and terminate the process if 
            # the timeout has been expired
            if sys.platform == 'linux2':
                os.kill(pid, signal.SIGTERM)
            elif sys.platform == 'win32':
                subp.terminate()
    
    if __name__ == '__main__':
        main()
    

提交回复
热议问题