【发布时间】:2017-12-15 19:25:24
【问题描述】:
所以,我正在开发一个小型控制台应用程序,它运行一个网络抓取过程,我希望能够在执行过程中为其提供控制台命令来控制它。为此,我需要某种形式的非阻塞键盘输入,因为程序可能会由于意外错误而自行终止,并且我不希望某些线程在终止时挂起并等待输入。
我已经讨论了以下内容:
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()
我的问题是,在while not stop: 行上,我的程序中将检查另一个条件,确定主循环是否已终止。如果发生这种情况,则主线程将停止,但后台 listener 线程仍将等待输入;我试图避免的情况。
我不喜欢这种方法,所以如果有一些替代方法可以获得非阻塞输入,那么我也会接受这个建议。
【问题讨论】:
-
我认为你应该在后台线程中进行抓取,而在 main 中进行输入循环。
-
我已经在后台线程上进行了抓取,但它可能会以我能够在主线程上检测到的方式终止。我仍然存在后台线程完成后主线程将等待输入的问题。这是由于 python 中
input方法的阻塞性质,所以我相当肯定这需要改变,但我不确定该怎么做。 -
你使用 Linux 吗? stackoverflow.com/q/3762881/1025391
-
不用担心,虽然我自己更喜欢 Linux,但这是在运行 Windows 10 的工作 PC 上。
-
我还应该提到,我查看了
msvcrt模块,但它似乎没有提供我想要的功能。它似乎一次只提供一个字符,而不是一行输入,虽然我知道我可以用它来组合一个输入行,但这可能比一切都值得更麻烦。
标签: python multithreading python-3.x console-application