Skip to content

Instantly share code, notes, and snippets.

@MawKKe
Last active October 12, 2024 12:31
Show Gist options
  • Save MawKKe/1866f99ebbfcc4bb9d62a107b4a19825 to your computer and use it in GitHub Desktop.
Save MawKKe/1866f99ebbfcc4bb9d62a107b4a19825 to your computer and use it in GitHub Desktop.
Terminal/Console flow control demo
"""
Terminal/Console flow control demo
Most terminals support ctrl+S/ctrl-Q for pausing and unpausing
writing to it, which can be useful in some situations.
However, note that the terminal pause does _not_ pause the whole process,
how terminal job control (ctrl-z) does. Instead, only the thread that
attempts to write to stdout will block, while other threads are free to
continue processing. Only way other threads would block is they, too,
attempted to write to stdout while the terminal was paused.
Below is a demo of this behaviour.
# Run terminal flow control demo:
1) in terminal 1, Start script: python3 terminal-flow-ctrl-demo.py
2) in terminal 2, run 'tail -f /tmp/threading.log'
3) in terminal 1, press ctrl-S (=pause).
Now, no new prints should appear in terminal 1, while prints keep appearing
in terminal 2.
If you press ctrl-Q (=resume) in terminal 1, the prints will resume again.
The immediate next print _may_ contain an old timestamp value that
possibly was in the buffers before terminal was paused. However,
any subsequent timestamps should reflect the *current* time.
You can also keep using ctrl+s/ctrl+q as many times as you want,
the background thread should keep printing into the log file without
interruption every time.
To exit the demo, press ctrl-C.
Neat!
"""
import threading
import time
import datetime
stop = threading.Event()
def write_log(path):
t = threading.current_thread()
with open(path, 'w') as f:
while not stop.is_set():
print(f'[background] time = {datetime.datetime.now()}', file=f)
f.flush()
time.sleep(1)
print('thread done')
try:
t1 = threading.Thread(target=write_log, args=('/tmp/thread.log',))
t1.start()
while True:
print(f'[main] time = {datetime.datetime.now()}')
time.sleep(1)
except KeyboardInterrupt:
stop.set()
t1.join()
print('bye')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment