Уведомления

Группа в Telegram: @pythonsu

#1 Июнь 17, 2011 10:27:56

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

bufsize в subprocess.Popen - баг или фича ? Давайте разберемся.

Ни разу не вводит. Укажите bufsize побольше и запустите two.py с ключем -u
Это же разные стороны соединения.



Офлайн

#2 Июнь 17, 2011 10:28:26

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

bufsize в subprocess.Popen - баг или фича ? Давайте разберемся.

JOHN_16
Выходит что параметр bufsize это всего лишь обманка? которая есть и в python2 и в python3 при этом также упоминается в официальной документации. Не красиво как то получается, вводит людей в заблуждение
Нет, не выходит. subprocess действительно устанавливает буфер stdout в соответствии со значением bufsize, но запущеный процесс об этом не может знать, поскольку нет стандартного способа об этом сказать. Вы путаете subprocess API и поведение python, запущенного как процесс. Они по большому счету никак не связаны.



Офлайн

#3 Июнь 17, 2011 11:08:47

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

bufsize в subprocess.Popen - баг или фича ? Давайте разберемся.

Хорошо, посмотрим на это с такой стороны, вот код в two.py выводит через секунду строку длиной 1024 символа, ну это можно сказать 1кб.
Так вот, Что нужно исправить что бы получилось что бы запустив one.py на экран отправлялись“пачки” вывода длиной в 8 итераций т.е. 8 кб ?



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#4 Июнь 17, 2011 11:19:53

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

bufsize в subprocess.Popen - баг или фича ? Давайте разберемся.

Нужно в one.py читать по 8 кб. Вот так:

s=p.stdout.read(8*1024)
Это же блокирующее чтение, будет ждать пока не прочитает.



Офлайн

#5 Июнь 18, 2011 11:01:04

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

bufsize в subprocess.Popen - баг или фича ? Давайте разберемся.

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



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#6 Июнь 19, 2011 12:14:36

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

bufsize в subprocess.Popen - баг или фича ? Давайте разберемся.

Параметр нужен, чтобы установить размер буфера для std* потоков процесса.
А вот дальнейшее зависит от процесса, который вы запускаете. Я специально показал пример с шеллом, который ничего с размером буфера не делает. А Питон делает.

Чтобы окончательно понять что тут к чему я бы посоветовал написать маленькую программку на Си и запускать ее. Тогда вы окончательно прочуствуете, что процесс получает тот буфер, который установил ему subprocess.Popen. Но если внутри процесса вы захотите его сменить, то сможете это сделать. Питон именно так и поступает.



Офлайн

#7 Июнь 20, 2011 10:50:08

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

bufsize в subprocess.Popen - баг или фича ? Давайте разберемся.

попробовал написать аналогичную программку , так как в C не силен то получилось не слишком красиво, код loop_print.c :

#include <stdio.h>
int main() {
char *base="************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************";
int i=100;
for (i; i<150; i++){
printf("%i%s\n",i, base);
sleep(1);
}
return 0;
}
В итоге так
1) поигрался с bufsize на примере скрипта на шеле, независимо от него вывод идет построчно.
2)поигрался с bufsize на примере программы на C, независимо от него вывод идет по 4 итерации = 4кб. компилировал банально
john_16@linux-home:~/C> gcc –version
gcc (SUSE Linux) 4.5.1 20101208
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

john_16@linux-home:~/C> gcc -o loop_print loop_print.c

Я что то не так на C написал? В общем где я ошибся?? уж больно хочется разобраться в этом вопросе.



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#8 Июнь 21, 2011 11:12:48

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

bufsize в subprocess.Popen - баг или фича ? Давайте разберемся.

Почитавши сорцы и маны я пришел к такой картинке:
При запуске программы на си открывается stdout со своим буфером. Видимо в вашем случае этот буфер равен 4кб.
Subprocess использует свою буферизацию в соответствии со значением bufsize. При этом для открытия файлов он использует io.open, причем для дескрипторов, приаттаченых к терминалу(наш случай?) он использует построчную буферизацию.
То есть получается, что если в самой программе буферизация отключена, то, несмотря на значение bufsize поток у нас буферизируется построчно, что мы и наблюдаем. Если же в самой программе буферизация включена, то мы получаем ваши 4 итерации, поскольку буфер 4килобайтный.
Это пока мои домыслы, поскольку времени не было попробовать.

Чтобы убедиться в частичной правильности моих выводов вы можете использовать для вывода не потоковые функции, а те, которые работают с дескрипторами(write с дескриптором STDOUT_FILENO, в данном случае). Либо с помощью setvbuf убрать буфер с потока stdout. Скорее всего в результате в вашем one.py получите построчный вывод, как и в случае с shell или python -u.
Потом, если захотите, можно будет подумать о том, как уйти от построчной буферизации и получить то, что вы хотели - при изменении bufsize в вызове subprocess.Open получить изменение в выводе.

PS: Вполне возможно что это частично или полностью бред. Нужно пробовать.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version