2015-06-30 2 views
4

Я пишу довольно сложный сценарий, который используетВозможно ли установить размер буфера труб при использовании asproccesses asyncio?

asyncio.create_subprocess_exec(sub_cmd, *sub_cmd_args, stdout=PIPE, stderr=PIPE) 

, чтобы обернуть вокруг другой программы Python - что я не могу изменить, постоянно или иным образом включать в себя непосредственно - захватить ее стандартный вывод/ERR для регистрации. Обернутый скрипт Python не использует параметр -u (небуферизованный), поэтому программа-обертка имеет тенденцию регистрировать большие буферизованные блоки. Если бы это был обычный subprocess.Popen, я мог бы просто передать bufsize=1, чтобы получить то, что я хочу, а именно, буферизацию строки. Однако, если добавить, что в asyncio.create_subprocess_exec() они ловушка для этого специально и я получаю:

<snip> 
    File "/usr/lib64/python3.4/asyncio/subprocess.py", line 193, in create_subprocess_exec 
    stderr=stderr, **kwds) 
    File "/usr/lib64/python3.4/asyncio/base_events.py", line 642, in subprocess_exec 
    raise ValueError("bufsize must be 0") 
ValueError: bufsize must be 0 

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

ответ

1

Я сначала доказал себе, что это действительно проблема буферизации труб, добавив -u к линии shebang завернутой программы. Я не мог полагаться на это как на решение, хотя из-за того, что такое изменение в конечном итоге скроется обновлениями ОС.

Я был в состоянии решить эту проблему, хотя в подобной манере, хотя:

  • Программа обертки является родительской программой трубы, поэтому она контролирует окружение своих дочерних программ.
  • Python должен подчиняться PYTHONUNBUFFERED=1 в своей унаследованной среде.
  • asyncio.create_subprocess_exec() поддерживает аргумент env= и многое другое, что может быть передано subprocess.Popen(); возможно, немного недостаточно документально, но просмотр кода делает это совершенно очевидным.

Так что я изменил мой вызов:

asyncio.create_subprocess_exec(sub_cmd, *sub_cmd_args, stdout=PIPE, stderr=PIPE, env={'PYTHONUNBUFFERED': '1'}) 

Это работало отлично и кредит идет к моему хорошему другу и техническим гуру.

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

  • Нет связанных вопросов^_^