So, I have a small console app I'm working on that runs a web-scraping process, and I want to be able to give it console commands mid-execution to control it. To do this I'll need some form of non-blocking keyboard input, as the program may self-terminate due to unexpected errors, and I don't want some thread hanging about and waiting for input when termination has occurred.
I have the following already hashed out:
import threading
import time
import queue
input_queue = queue.Queue()
command_input_event = threading.Event()
def kbdListener():
global input_queue, command_input_event
kbdInput = ''
while kbdInput.lower() not in ['quit', 'exit', 'stop']:
kbdInput = input("> ")
input_queue.put(kbdInput)
command_input_event.set()
input_queue.join()
listener = threading.Thread(target=kbdListener)
listener.start()
stop = False
while not stop:
if command_input_event.is_set():
while not input_queue.empty():
command = input_queue.get()
if command.lower() in ['quit', 'exit', 'stop']:
print('Stopping')
while not input_queue.empty():
input_queue.get()
input_queue.task_done()
input_queue.task_done()
stop = True
break
else:
print('Command "{}" received and processed'.format(command))
input_queue.task_done()
My problem is that on the line while not stop:
there will be another condition being checked in my program, that determines if the main loop has terminated. If this eventuality was to occur then the main thread would stop, but the background listener
thread would still be waiting for input; the situation I'm trying to avoid.
I'm not tied in to this approach, so if there is some alternative method for getting a non-blocking input, then I would be open to that advice as well.