How to Print Stdout Immediately

How to print out Python message to linux stdout immediately

You could call flush on stdout. If it is possible and practical for you to adjust your code to flush your buffers after the print call, in test.py:

from sys import stdout
from time import sleep

def log():
while True:
print('Test log message')
# flush your buffer
stdout.flush()
sleep(1)

While running this logging test, you can check the nohup.txt file and see the messages being printed out in realtime.

How to read stdout immediately in Python subprocess

An example for you where you read and write to the child several times (as you stated in a comment under the question).

The subprocess (test.py) will:

  • read a line
  • convert each one to upper case, and write it back,
  • sleep 2 seconds
  • repeat until no more input, and then write a final line

The main process (main.py) will:

  • three times:
    • write a line of input to the subprocess
    • read the answer and say how long it took to get the answer back
    • sleep 5 seconds
  • at the end, read any final output using communicate, and report this

Here is the output of the code that is shown below:

writing to child: hello world 0
child replied with: HELLO WORLD 0
got answer back within 0.00022 seconds

writing to child: hello world 1
child replied with: HELLO WORLD 1
got answer back within 0.00012 seconds

writing to child: hello world 2
child replied with: HELLO WORLD 2
got answer back within 0.00021 seconds

final output from child: finishing

And here is the code:

test.py

import sys
import time

while True:
value = sys.stdin.readline()
if not value:
break
sys.stdout.write(value.upper())
sys.stdout.flush()
time.sleep(2)

sys.stdout.write("finishing\n")

main.py

from subprocess import Popen, PIPE, STDOUT
import time

child = Popen(['python.exe', 'test.py'], stdin=PIPE, stdout=PIPE, stderr=STDOUT)
time.sleep(1)

for i in range(3):
data_in = f"hello world {i}"
print(f"writing to child: {data_in}")

time0 = time.time()
child.stdin.write(f"{data_in}\n".encode())
child.stdin.flush()
data_out = child.stdout.readline()
time1 = time.time()

result = data_out.decode().strip()
elapsed_time = time1 - time0
print(f"child replied with: {result}")
print(f"got answer back within {elapsed_time:.5f} seconds\n")
time.sleep(5)

output, error = child.communicate()
print(f"final output from child: {output.decode()}")

(Tested on Linux using python instead of python.exe - hopefully it will work equally on Windows although I can't test this.)

As you can see, the answer is received without having to wait for the sleep to complete.

(Obviously if the sleep time in the parent is reduced to below about 2 seconds, then the child would not be ready to receive the data when it is sent, so then there would be more of a wait to get an answer back.)

With this sort of two-way communication, it is very easy to end up in a deadlock situation (each process is waiting for the other to do something). To avoid that, each process writes exactly one line each time, ensuring that it ends with a newline, and immediately flushes the output buffer -- and the reading process uses readline() to read exactly one line (reads until newline). Then hopefully the two should remain in step and avoid deadlocks.

How can I print text immediately without waiting for a newline in Perl?

You need to set autoflush for STDOUT. Example:

use IO::Handle;
STDOUT->autoflush(1);
foreach (1..20) {
print '.';
sleep(1);
}

printf doesn't print a string immediately

The output stream stdout is buffered by default, so if you want immediate output you'll need to flush the output stream - using fflush - or cause a newline to be printed in the printf:

printf("Starting nets allocation...");
fflush(stdout);

Or:

printf("Starting nets allocation...\n");

Note that you can also control buffering at a file pointer level using the setbuf function from stdio.h:

setbuf(stdout, NULL);

The second argument to setbuf is a buffer supplied by the caller to be used for buffering output to the stream. Passing NULL indicates that buffering is to be disabled, and is equivalent to:

setvbuf(stdout, NULL, _IONBF, 0);

which also disables buffering on the specified stream.

See docs for setbuf here.

How to print with end= immediately in Python 3?

You need to flush stdout:

print("first", end=" ", flush=True)

stdout is line buffered, which means the buffer is flushed to your screen every time you print a newline. If you are not printing a newline, you need to flush manually.

For anyone not yet using Python 3.3 or newer, the flush keyword argument is new in 3.3. For earlier versions you can flush stdout explicitly:

import sys

print("first", end=" ")
sys.stdout.flush()

How can I flush the output of the print function?

In Python 3, print can take an optional flush argument:

print("Hello, World!", flush=True)

In Python 2, after calling print, do:

import sys
sys.stdout.flush()

By default, print prints to sys.stdout (see the documentation for more about file objects).

C: printf does not output immediately

Since you use scanf to wait for user input, it will wait until you give some input to the program.

printf doesn't put all of the characters to the screen immediately, it buffers it's output. And as long as your program doesn't terminate or you don't call flush(stdout)
to flush the buffer or you don't put newline character \n at the end of first parameter to printf the output won't be printed to the screen.

change your call to printf to:

printf("Enter radius\n: ")
use newline so that the string is printed immediately and buffer is flushed

or if you do not want to use newline

printf("Enter radius: ")
fflush(stdout)

call fflush(stdout) to manually flush the output buffers.



Related Topics



Leave a reply



Submit