在Linux中使用Python:异步将用户输入放入队列
我正在尝试运行一个程序,这个程序会在工作完成时接收输入。我查阅了很多资料,也看了文档。我在Debian系统上运行这个程序,了解到我可以使用getch函数来接收字符,而不需要按回车键。简单来说,我想在我的无限循环中实现以下几点:
- 接收输入(我在这里尝试了线程,但没成功)
- 把输入放入队列中
- 如果没有正在运行的工作,就用队列前面的项目作为变量开始工作
我还在运行线程模块来执行其他指令。请问有没有办法做到这一点?
更新:这是我到目前为止尝试过的:
首先,我尝试使用线程模块中的计时器来避免等待,代码大致是这样的:
def getchnow():
def time_up():
answer= None
print 'time up...'
wait = Timer(5,time_up) # x is amount of time in seconds
wait.start()
try:
print "enter answer below"
answer = getch()
except Exception:
print 'pass\n'
answer = None
if answer != True: # it means if variable have somthing
wait.cancel() # time_up will not execute(so, no skip)
return answer
line = getchnow()
#Add line variable to queue
#Do stuff with queue
问题是,它仍然在等待用户输入。
然后,我尝试把getch函数放到另一个线程中。
q = Queue.Queue
q.put(getch())
if q.get() != True: # it means if variable have somthing
line = q.get()
#Add line variable to queue
#Do stuff with queue
这个尝试让我什么都做不了。
2 个回答
0
我也用过 [i, o, e] = select([sys.stdin.fileno()], [], [], 2)
这个方法,不过我听说在Windows上可能不太好使。如果还有人需要一个多线程的、非阻塞输入的例子:
import threading
import sys
import time
bufferLock=threading.Lock()
inputBuffer=[]
class InputThread(threading.Thread):
def run(self):
global inputBuffer
print("starting input")
while True:
line=sys.stdin.readline()
bufferLock.acquire()
inputBuffer.insert(0,line)
bufferLock.release()
input_thread=InputThread()
input_thread.start()
while True:
time.sleep(4)
bufferLock.acquire()
if len(inputBuffer)>0:
print("Popping: "+inputBuffer.pop())
bufferLock.release()
0
我看了这个链接的更多内容,发现底部有我想要的实现。
我在Linux上使用了select模块来实现非阻塞的功能。 如果没有收到输入,它会在(这里是5秒)后超时。 特别适合在线程中使用,这样getch调用就不会阻塞,可以让线程干净地退出。
# This class gets a single character input from the keyboard
class _GetchUnix:
def __init__(self):
import tty, sys
from select import select
def __call__(self):
import sys, tty, termios
from select import select
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
[i, o, e] = select([sys.stdin.fileno()], [], [], 2)
if i:
ch=sys.stdin.read(1)
else:
ch=''
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
getch = _GetchUnix()
# End Class