Форум сайта python.su
0
Всем привет!
Объясните, пожалуйста, как работают stdin, stdout при выполнении подобной команды в терминале:
prog1.py | prog2.exe
Офлайн
221
prog1.py в течении своей работы посылает строки на стандартный поток вывода (sys.stdout) которые операционной системой хранятся в специальном буфере. По завершении работы процесса запускается процесс prog2.exe на стандартный поток которого передается содержание буфера.
Таким образом передается только цельный фрагмент данных, нельзя организовать таким образом передачу информации кусочками.
Насколько я знаю в Windows и linux это работает идентично.
Однако в UNIX системах существуют UNIX Domain Socket - сокеты для межпроцессного взаимодействия. Их, пожалуй, главное отличие от каналов в возможности дву направленного обмена сообщениями, синхронно и асинхронно
Офлайн
857
kolunaНу, как у python есть три потока, так и у prog2.exe есть три потока. Поток вывода python соединяется с потоком ввода prog2.exe. (Программа python пишет в то же место, откуда читает prog2.exe.)
Объясните, пожалуйста, как работают stdin, stdout при выполнении подобной команды в терминале:
kolunaС момента запуска.
В какой момент вывод prog1 попадает на ввод prog2?
kolunaВ данном случае нет.
Есть ли различия для Linux и Windows?
JOHN_16Нет, они сразу оба запускаются и всё, что успевает вывестись из первой программы, сразу передаётся во вторую.
По завершении работы процесса запускается процесс prog2.exe на стандартный поток которого передается содержание буфера.
[guest@localhost ~]$ python3 -c 'print(1); input(); print(2)' | cat -n
1 1
x
2 2
[guest@localhost ~]$
Отредактировано py.user.next (Ноя. 27, 2014 05:05:36)
Офлайн
221
py.user.next
Таки да. Был не прав в своих суждениях. Все дело в буферизации вывода. Пример в linux:
#one.py import time for i in xrange(5): print 'I can do it, i will print value {}'.format(i) time.sleep(1)
python one.py | tee
import time, sys for i in xrange(5): print 'I can do it, i will print value {}'.format(i) sys.stdout.flush() time.sleep(1)
import time, sys for i in xrange(500): print 'I can do it, i will print value {}'.format(i) time.sleep(0.01)
Офлайн
857
JOHN_16
Все дело в буферизации вывода.
At program startup, three text streams are predefined and need not
be opened explicitly --- standard input (for reading conventional
input), standard output (for writing conventional output), and
standard error (for writing diagnostic output). When opened, the
standard error stream is not fully buffered; the standard input and
standard output streams are fully buffered if and only if the stream
can be determined not to refer to an interactive device.
#include <stdio.h>
#include <unistd.h>
int main(void)
{
int i;
for (i = 0; i < 3; i++) {
printf("Test %d\n", i);
sleep(1);
}
return 0;
}
[guest@localhost c]$ .ansi t.c -o t
[guest@localhost c]$ ./t
Test 0
Test 1
Test 2
[guest@localhost c]$
[guest@localhost c]$ ./t | cat -n
1 Test 0
2 Test 1
3 Test 2
[guest@localhost c]$
[guest@localhost ~]$ python3 -c 'import time; print(1); time.sleep(2); print(2)'
1
2
[guest@localhost ~]$ python3 -c 'import time; print(1); time.sleep(2); print(2)' | cat -n
1 1
2 2
[guest@localhost ~]$
Офлайн
0
По поводу того, что процессы работают параллельно и данные передаются постоянно - понятно, спасибо за разъяснения.
Какой размер буферов stdin, stdout по умолчанию?
Можно ли изменить размер буфера и получить информацию о количестве символов в нем?
Что происходит, когда буфер stdin переполняется или близок к этому? Читал, что процесс слева от ‘|’ приостанавливается операционной системой, пока процесс справа от ‘|’ не вычитает все данные (по крайней мере для Линукс).
Не понятно, может ли буфер переполниться и потеряются ли данные или нет?
Офлайн
857
kolunaBUFSIZ - платформозависимая константа, 8 килобайт.
Какой размер буферов stdin, stdout по умолчанию?
kolunaЕсли тебе это понадобилось в питоне, то что-то не так делаешь. В C есть функции для изменения не только размера, но и адреса.
Можно ли изменить размер буфера и получить информацию о количестве символов в нем?
kolunaСодержимое выталкивается и буфер делается пустым.
Что происходит, когда буфер stdin переполняется или близок к этому?
kolunaНу, наверняка блокируется для вывода, пока читатель не прочитает.
Читал, что процесс слева от ‘|’ приостанавливается операционной системой, пока процесс справа от ‘|’ не вычитает все данные
kolunaФункции вывода следят за его размером. Если там есть место, они дописывают, если нет - вызывают выталкивание и обнуление и пишут в пустой.
Не понятно, может ли буфер переполниться и потеряются ли данные или нет?
Отредактировано py.user.next (Ноя. 28, 2014 01:34:17)
Офлайн
0
Т. е., если программы работают нормально, то данные при обмене между программами через stdout-stdin не теряются?
Офлайн