Буферизация потока вывода: первый взгляд

buferizaciya potoka vyvoda pervyj vzglyad Системные инструменты параллельного выполнения

Обратите внимание, что в последней проверке, в предыдущем фрагменте программного кода, не предпринимается попытка прочитать вывод команды. В подобных ситуациях может потребоваться запускать целевой сценарий в небуферизованном режиме, то есть запускать интерпретатор Python с флагом u, или изменить сценарий, чтобы он выталкивал выходной буфер вручную с помощью функции sys.stdout.flush. В противном случае текст, выводимый в стандартный поток вывода, не будет вытолкнут из буфера стандартного потока вывода при вызове функции os._exit. По умолчанию при подключении канала, как в данном примере, стандартный поток вывода работает в режиме полной буферизации — при подключении к терминалу в буфер помещается только одна строка:

>  >> pipe = os.popen(‘python testexit_os.py’)

>  >> pipe.read() # буферы не выталкиваются при выходе ‘’

>  >> pipe = os.popen(‘pythonu testexit_os.py’) # принудительный

>  >> pipe.read() # небуферизованный режим

‘Bye os world\n’

Странно, но, несмотря на то, что имеется возможность передавать функциям os.popen и subprocess.Popen аргумент, управляющий режимом и буферизацией, — в данном случае это не поможет. Аргументы передаются инструментам со стороны вызывающего процесса, с конца канала, работающего в порожденной программе, как поток ввода, а не как поток вывода:

>  >> pipe = os.popen(‘python testexit_os.py’, ‘r’, 1) # построчная буферизация

>  >> pipe.read() # но мой канал — это не поток вывода программы!

>  >> from subprocess import Popen, PIPE

>  >> pipe = Popen(‘python testexit_os.py’, bufsize=1, stdout=PIPE) # для моего

>  >> pipe.stdout.read() # канала —

b’’ # не поможет

Аргументы, определяющие режим буферизации, воздействуют на поток вывода вызывающего процесса, через который он записывает данные в стандартный поток ввода команды, а не на поток вывода команды, откуда вызывающий процесс читает данные.

При необходимости запускаемый сценарий может сам, вручную выталкивать выходные буферы — периодически или перед принудительным завершением. Подробнее о буферизации мы поговорим, когда будем обсуждать возможность возникновения ситуации взаимоблокировки далее в этой главе, и еще раз — в главах 10 и 12, где мы узнаем, как все это увязывается с сокетами. Поскольку мы вспомнили про модуль subprocess, рассмотрим теперь предоставляемые им инструменты завершения программ.

Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, I том, 2011

Оцените статью
Секреты программирования
Добавить комментарий