osdir.com


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

stderr writting before stdout


Please don't top post; I have rearranged your message so that the 
discussion reads from top to bottom. Reponse below.

On 24May2020 10:04, Souvik Dutta <souvik.viksou at gmail.com> wrote:
>On Sun, 24 May, 2020, 9:57 am Souvik Dutta, <souvik.viksou at gmail.com> 
>wrote:
>> Is there any precedence or priority order by which sys.stderr.write() 
>> and
>> sys.stdout.write() works. Because when running the below code...
>>
>> import sys
>> sys.stdout.write("Writting")
>> sys.stderr.write("No errors \n")
>>
>> No errors is written (displayed) first and writting is written later. Why
>> does this happen?
>
>Also this code maintains order i.e. writting is displayed before no 
>errors.
>Why is that?
>
>import sys
>sys.stdout.write("Writting \n")
>sys.stderr.write("No errors \n")

This is all to do with buffering.

Output streams are buffered (unless you go out of your way to avoid it).  
This means that for throughput performance reasons, when you go 
f.write(...) the daa are written into an in memory buffer, and not yet 
to the file itself. The buffer is conventionally of fixe size.

A fully buffered stream tries to minimise the OS-write calls (which copy 
from the pogramme to the operating system) because they are 
comparitively expensive. For thorughtput, writing a lot of data in bulk, 
this is a win because the OS-write calls are as few as possibly.

An unbuffered stream calls the OS-write as soon as any data are 
received; there wouldn't even be an in memory beffer at all. This 
presents data to the OS as soon as possible, at the cost of more frequnt 
OS-write calls.

In between these 2 extremes are onther policies. One such is line 
buffering: the contents of the buffer are written to the OS when there 
is a complete line in the bufeer (i.e. when a newline character arrives 
in the data). This is common on terminals, and writes complete lines to 
the terminal. This is common for writing "text" to a terminal, and makes 
more OS-writes that full buffeing and fewer than unbuffered as a 
comprimise to present timely display to a human.

You can force an OS-write of a buffered stream by calling its flush() 
method.

Conventionally, on UNIX systems, an output stream connected to a regular 
file is fully buffered, to maximise bulk data writing throughput. An 
output stream connected to a terminal is line buffered. Except for 
stderr, which is _unbuffered_ because it is felt that error messages 
should always show up as soon as possible.

These different policies explain the behaviour you see.

By inserting:

    sys.stdout.flush()

calls at various points for can force OS-write calls and see data 
immediately, which will make this more clear to you.

Cheers,
Cameron Simpson <cs at cskk.id.au>