Flush stdin

Marko Rauhamaa marko at pacujo.net
Tue Oct 21 06:41:07 CEST 2014


Dan Stromberg <drsalists at gmail.com>:

> Often with TCP protocols, line buffered is preferred to character
> buffered,

Terminal devices support line buffering on write.

Line buffering on read is an illusion created by higher-level libraries.
The low-level read function reads in blocks of bytes.

> Also, it's a straightforward way of framing your data, to avoid
> getting messed up by Nagle or fragmentation.

Nagle affects the communication between the peer OS kernels and isn't
directly related to anything the application does. Also, Nagle doesn't
play any role with pipes.

>> ========================================================================
>> $ bash ./test.sh | strace python3 ./test.py
>> ...
>> read(0, "x", 4096)                      = 1
>> read(0, "x", 4096)                      = 1
>> read(0, "x", 4096)                      = 1
>> read(0, "x", 4096)                      = 1
>> read(0, "x", 4096)                      = 1
>> fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 3), ...}) = 0
>> mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1,
>> 0) = 0x7f3143bab000
>> write(1, "120\n", 4120
>> )                    = 4
>> ...
> ========================================================================
>
> This is tremendously inefficient.  It demands a context switch for
> every character.

Inefficiency isn't an issue when you generate one byte a second. If data
were generated at a brisker pace, "read(0, ..., 4096)" could get more
bytes at a time. Notice that even if the Python code requests 5 bytes,
CPython requests up to 4096 bytes in a single read.


Marko



More information about the Python-list mailing list