【问题标题】:Python subprocess call hangsPython子进程调用挂起
【发布时间】:2013-08-18 21:33:34
【问题描述】:

Python 版本:2.6.7 我在执行 18 次的 for 循环中有以下 subprocess.call,但是,该进程在第 19 次循环中不断挂起:

if config.get_bool_option(NAME, 'exclude_generated_code', True):
            for conf in desc.iter_configs():
                for gen in desc.iter_generators(conf):
                    generator.initialize_generated_path(gen, desc)
                    for genpath in gen.generated_path:
                        os.rename(cov_file, cov_file+'.temp')
                        exclude = ['lcov']
                        exclude += ['-r', cov_file+'.temp', '"'+genpath+'/*"']
                        exclude += ['-o', cov_file]
                        if verbose: Tracer.log.info("Running "+ ' '.join(exclude))
                        try:
                            subprocess.call(' '.join(exclude), stdout=out, stderr=out, shell=True)
                        except subprocess.CalledProcessError, e:
                        if verbose: Tracer.log.info("TESTING: Got Exception \n") 

控制台输出如下:

Running lcov -r /remote/XXXXXX/coverage.19.temp "/remote/XXXXXX/xml/2009a/generated/*" -o /remote/XXXXX/gcov/coverage.19

由于我对python脚本不是很熟悉,所以我只是在这里徘徊是否我做错了什么......我怀疑某个地方出现了死锁..

stdout, stderr = process.communicate() 会处理这些问题吗?

请专家解答 subprocess.call 在哪些情况下会挂起? 非常感谢

【问题讨论】:

    标签: python python-2.7 subprocess


    【解决方案1】:

    在使用子流程时,我倾向于这样做:

    is_running = lambda: my_process.poll() is None
    
    my_process = subprocess.Popen(' '.join(exclude), 
                                  stdout=subprocess.PIPE, 
                                  stderr=subprocess.PIPE,
                                  shell=True)
    
    # Grab all the output from stdout and stderr and log it
    while is_running():
        rlist, wlist, xlist = select.select([my_process.stdout, my_process.stderr], [], [], 1)
    
    # Log stdout, but don't spam the log
    if my_process.stdout in rlist and verbose:
        # Adjust the number of bytes read however you like, 1024 seems to work 
        # pretty well for me. 
        Tracer.log.debug(my_process.stdout.read(1024))
    
    # Log stderr, always
    if my_process.stderr in rlist:
        # Same as with stdout, adjust the bytes read as needed.
        Tracer.log.error(my_process.stderr.read(1024))
    

    我在过去看到标准输出的东西只是在我的日志中转储了一堆空行,这就是我在调试级别记录的原因。这会在开发过程中打印到我的日志中,但从未在生产中写入,因此我可以安全地将其留在代码中进行调试,而不会将垃圾放入日志中。

    希望这有助于揭示您的程序挂起的位置以及导致挂起的原因。

    【讨论】:

      猜你喜欢
      • 2017-02-28
      • 2014-08-22
      • 2016-11-02
      • 2012-09-07
      • 2015-07-07
      • 2012-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多