终止时,在OSX活动监视器中挂起python子进程(具有子进程的进程)

时间:2013-06-25 08:11:37

标签: python macos subprocess multiprocessing

我正在为我编写的udp服务器编写测试工具。我们的想法是使用multiprocessing.pool为服务器的多个实例(per this question)执行subprocess.call命令。 udp服务器是另一个python程序,由3个进程组成(main,http接口和udp服务器)。在我尝试编写测试脚本时,当我使用CTRL + C终止测试脚本时,我总是在我的活动监视器中获得2-5个挂起的python2.7进程。

我的尝试:

  1. vanilla subprocess
  2. 处理bash未连接到终端(see this question
  3. 的子流程
  4. multiprocess.pool,也使用简单的test.py脚本创建挂起进程(见下文)
  5. 我尝试在服务器代码中添加子进程杀死无济于事。当我在终端内运行服务器时,它正确响应CTRL + C.我假设它与服务器内的子进程有关,因为(1)和(2)对test.py脚本没有任何问题。


    1)只使用子流程:

    args0 = [sys.executable, server_path, '-p', '7000', '-t', '8000', '-u', '9000']
    args1 = [sys.executable, server_path, '-p', '7001', '-t', '8001', '-u', '9001']
    
    p0 = subprocess.Popen(args0)
    p1 = subprocess.Popen(args1)
    

    2)使用带有stdout,pipe,os.kill的子进程:

    p0 = subprocess.Popen(  args0, 
                            stdout=subprocess.PIPE, 
                            stderr=subprocess.STDOUT, 
                            close_fds=True)
    print "running for 5s..."
    time.sleep(5)
    os.kill(p0.pid, signal.SIGTERM)
    

    3a)test_harness.py(with pool)

    import sys, os, time
    import subprocess, multiprocessing
    
    def work(cmd):
        return subprocess.call(cmd) # , shell=False
    
    def main():
        server_path = os.getcwd() + '/' + 'test.py'
    
        args0 = [sys.executable, server_path, '-p', '7000']
        # args1 = [sys.executable, server_path, '-p', '7001']
        tasks = [args0]
    
        pool = multiprocessing.Pool(processes=1)
        pool.map_async(work, tasks)
        time.sleep(3)
        pool.terminate()
    
    if __name__ == '__main__':
        main()
    

    3b)test.py

    def main():
        while True:
            a = 1
    
    if __name__ == '__main__':
        main()
    

1 个答案:

答案 0 :(得分:0)

终于有了工作。此代码生成两个多线程服务器实例,作为测试工具内的子进程。您可以从子进程获得所有控制台输出,当您从终端CTRL + C测试工具时,所有子进程也会死亡。 subprocess.Popen最终不适合我。

def runInstance(args):
    # NOTE: We don't do the stdout or stderr args
    p = subprocess.call(args, 
                        # stdout=subprocess.PIPE, 
                        # stderr=subprocess.STDOUT, 
                        close_fds=True, 
                        shell=True
                        )

def main():
    print "Starting test harness..."
    server_path = os.getcwd() + '/' + 'server.py'
    args0 = [sys.executable, server_path, '-p', '7000', '-t', '8000', '-u', '9000']
    args1 = [sys.executable, server_path, '-p', '7001', '-t', '8001', '-u', '9001']

    # Start server instances
    # NOTE: It is target=runInstance, not target=runInstance()
    p0 = multiprocessing.Process(target=runInstance, args=(' '.join(args0),))
    p1 = multiprocessing.Process(target=runInstance, args=(' '.join(args1),))
    p0.start()
    p1.start()