2013-08-16 55 views
4

Python版本:2.6.7 我在for循环内被exectuted 18倍,然而,过程中不断地悬挂在19环以下subprocess.call:Python的子进程调用挂起

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()会处理这些问题吗?

任何专家的回答,在哪些情况下,子过程。请挂? 非常感谢

+0

检查第19条命令是否自行挂起,检查可用磁盘空间和/或添加'close_fds = True'参数(确保在循环中释放其他资源)。 – jfs

+0

与悬而未决的问题无关:1.'subprocess.call()'不会引发'CalledProcessError',您可能会将它与'subprocess.check_call()'混淆。2.您可能不需要'shell = True';您可以将该命令作为列表传递。 3.要合并stdout/stderr,你可以设置'stderr = subprocess.STDOUT'。 – jfs

回答

4

当使用子,我倾向于做这样的事情:

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)) 

我见过的标准输出的东西只是倾倒了一堆空行中我的日志,在过去,这是为什么我在调试级别记录它。它在开发过程中会打印到我的日志中,但从不写入生产环境,所以我可以放心地将它放在代码中进行调试,而不会在日志中放入垃圾。

希望这可以帮助揭露您的程序挂起的位置以及导致它的原因。