Jack
Jack

Reputation: 951

How to make Python's print() non-blocking?

I am running a Python script on a Rasberry Pi which appears to freeze intermittently on the print() call. The script only freezes occasionally and continues when someone focuses on the terminal and presses the "enter" button or hits ctrl+c.

My guess is that the problem here is that the print() call is waiting to get some kind of response back from the terminal which it doesn't get when the user does something unexpected, such as highlight text, right-click drag, or some other thing (which I am unable to replicate). To be clear, the script hangs indefinitely in this case, and not for the 120 seconds specified in the time.sleep() call directly below.

My question is this: is there any print call I can use in python which doesn't wait to get a response back from the console so that it doesn't freeze in unknown cases like the above?

I've put my code below, although the specifics of what it does are not particularly relevant to the question.

while True:
    directory_pump_files =  glob.glob("./pumplog*.csv") #read in some files from the file system

    for file_path in directory_pump_files:
        try_upload_file(file_path, pump_files_done, "/batchUpload/create") #upload the pump file

        
    directory_log_files =  glob.glob("./log*.csv")

    for file_path in directory_log_files:
        try_upload_file(file_path, log_files_done, "/batchUpload/SensorReadings") #upload the log file
    print ("sleep")
    time.sleep(120)

Upvotes: 3

Views: 2016

Answers (1)

Jaap Joris Vens
Jaap Joris Vens

Reputation: 3550

It might be an issue with the terminal's buffering mechanism. Normally, the buffer is flushed when a newline is encountered, but things could work differently on a Raspberry Pi.

You can try to use the flush argument. From help(print):

print(...)
    print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
    
    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file:  a file-like object (stream); defaults to the current sys.stdout.
    sep:   string inserted between values, default a space.
    end:   string appended after the last value, default a newline.
    flush: whether to forcibly flush the stream.

By using print("sleep", flush=True) the string will be printed immediately.

Upvotes: 3

Related Questions