Объясните, пожалуйста, как работают stdin, stdout при выполнении подобной команды в терминале:
prog1.py | prog2.exe
В какой момент вывод prog1 попадает на ввод prog2?
Только при завершении prog1?
Есть ли различия для Linux и Windows?
prog1.py | prog2.exe
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 ~]$
#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)
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 ~]$
kolunaBUFSIZ - платформозависимая константа, 8 килобайт.
Какой размер буферов stdin, stdout по умолчанию?
kolunaЕсли тебе это понадобилось в питоне, то что-то не так делаешь. В C есть функции для изменения не только размера, но и адреса.
Можно ли изменить размер буфера и получить информацию о количестве символов в нем?
kolunaСодержимое выталкивается и буфер делается пустым.
Что происходит, когда буфер stdin переполняется или близок к этому?
kolunaНу, наверняка блокируется для вывода, пока читатель не прочитает.
Читал, что процесс слева от ‘|’ приостанавливается операционной системой, пока процесс справа от ‘|’ не вычитает все данные
kolunaФункции вывода следят за его размером. Если там есть место, они дописывают, если нет - вызывают выталкивание и обнуление и пишут в пустой.
Не понятно, может ли буфер переполниться и потеряются ли данные или нет?