Python子进程调用卡住了

5

Python版本:2.6.7 我在一个for循环中有以下subprocess.call,该循环执行18次,但是进程在第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会挂起?谢谢。

1个回答

4
使用 subprocess 时,我倾向于像这样做:
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))

我曾经看到标准输出(stdout)会在我的日志中倾倒一堆空行,这就是为什么我将其记录在调试级别(debug level)的原因。这会在开发期间打印到我的日志中,但在生产环境中永远不会被写入,因此我可以安全地将其留在代码中进行调试,而不会在他们的日志中放置垃圾。
希望这可以帮助暴露程序挂起的位置和原因。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接