2013-08-16 4 views
4

версии Python: 2.6.7 У меня есть следующее subprocess.call в для цикла, который exectuted 18 раз, однако, процесс постоянно висит на 19-е петли: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 

поскольку я не очень хорошо знакомы с питона сценариев, я просто бродил ли я делаю что-то здесь не так ... Я подозреваю, что в тупик где-то ..

Имеют ли деловые вопросы 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)) 

Я видел стандартный вывод вещь просто дамп кучи пустых строк в моих журналах в прошлом, что почему я регистрирую это на уровне отладки. Это печатает мои журналы во время разработки, но никогда не записывается на производство, поэтому я могу спокойно оставить его в коде для отладки, не помещая мусор в свои журналы.

Надеюсь, это поможет разоблачить, где ваша программа висит и что вызывает ее.

Смежные вопросы