Python in Linux: Put user input asynchronously into queue

浪子不回头ぞ 提交于 2019-12-25 01:44:01

问题


I am trying to run a program that takes in input as a job is getting done. I have looked through several forms, and looked into the documentation. I'm running this in Debian, and I understand that I can use this getch function to receive characters without hitting the return key. To break it down, this is what I am trying to implement in my infinite while loop

  • Take in input (threading didn't work here for me
  • Put input into Queue
  • If there are no running jobs, start the job with the item in front of the queue as a variable

I am also running the threading module to execute another instruction. Is there any way I can do this?


Update: This is what I have tried so far:

First, I tried using a timer from the threading module to stop it from waiting, which went something like this.

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

The problem here is that it still waited for user input.

I then tried to put the getch function into another thread.

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

This attempt doesn't let me do anything.


回答1:


I read more of this link, and there was an implementation of what I wanted at the bottom.

I used the select module for a Non-Blocking implementation on Linux. This times out in (5 seconds here) if no input is received. Particularly useful when used in a thread, so that the getch call is non-blocking and will allow the thread to exit cleanly

# 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



回答2:


I've also used [i, o, e] = select([sys.stdin.fileno()], [], [], 2), but I've heard it might not work on windows. If anyone still needs a multi-threaded, non-blocking input example:

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()


来源:https://stackoverflow.com/questions/15302883/python-in-linux-put-user-input-asynchronously-into-queue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!