Reputation: 35
I have a separate Python process that, after starting, continuously outputs through its stdout trajectory points to the main app which carries them, after some processing, to a device over a serial port.
It can non-deterministically happen that sending trajectory points would have to be stopped. If that happens, then a slow-down trajectory points would have to be generated and send, and only the process has data to do it.
However I can't listen to a stop command in that process with, for ex., input()
, and generate trajectory because of GIL.
How can I both listen on stdin and generate the trajectory?
I don't want to place the trajectory generation or the slow-down bit in the main app, because it will complicate things a lot. I also would rather not write the whole app in another language like C++.
Upvotes: 0
Views: 80
Reputation: 18000
you can listen on stdin
in a daemon worker thread, and notify the main thread through a threading.Event, daemon threads are fire-and-forget, so they are used for such tasks.
import threading
import time
stop_event = threading.Event()
def listen_for_stop():
while True:
input_value = input()
if input_value == "stop":
stop_event.set()
break
listener = threading.Thread(target=listen_for_stop,
daemon=True)
listener.start()
while True:
if not stop_event.is_set():
print("outputting trajectory")
else:
print("outputting stop tranjectory")
break
time.sleep(1)
outputting trajectory
stop
outputting stop tranjectory
the GIL stops threads from executing in parallel, they just take turns executing (5-10ms time slices), but the listener is blocked reading input so it is sleeping and the main thread is not interrupted, the worker only wakes up when input arrives.
you don't necessarily need to listen on stdin, you can do that on a named pipe or a socket if you want to leave stdin for other uses, and at least on windows using a socket allows asnychronous listening on the socket with asyncio, whereas on unix you can listen on stdin asynchronously, which you will need to do if you want to stop the listener. (windows doesn't support async reads from stdin)
Upvotes: 0