输入()被阻塞的使用过程(input() is blocking the use of proces

2019-10-19 21:24发布

我有一个多问题。 如果我在一个线程等待输入的过程中没有启动。

该类把输入到后台队列:

class InputCatcher(Thread):
    def __init__(self, input_queue):
        Thread.__init__(self)
        self.input_queue = input_queue

    def run(self):
        while True:
            self.input_queue.put(input()) # <<-- Without this it works!

不会启动类:

class Usb(Process):
    def __init__(self, port, ctrl=Controller()):
        Process.__init__(self)
        self.usb_port = port
        self.ctrl = ctrl


    def run(self):
        self.ctrl.usb_ports.append(self.usb_port)
        ser = Serial(self.usb_port, 115200)
        while True:
            dsl = ser.readline()
            self.ctrl.get_dataset_queue().put(['USBDS', dsl])
            print(dsl)

从...开始:

ic = InputCatcher(self.input_queue)
ic.setDaemon(True)
ic.start()

usbs = []
for port in usb_ports():
    if not port in ctrl.xbee_ports:
        usbs.append(Usb(port, ctrl))

for usb in usbs:
    usb.daemon = True
    usb.start()

Answer 1:

当你调用input ,它阻挡了整个Python过程,而不仅仅是它运行在线程这是因为从标准输入读,像其他任何类似文件的对象读取,包括使阻塞的系统调用-也就是说, input阻断等待用户输入发生在操作系统级别,而不是内部的Python的自己的线程管理代码。 Python的线程的操作系统进程调度基本上是不可见,所以Python本身已被封锁。

阻挡周围像这样的问题,通常的方法是使用过程中,而不是线程。 如果您InputCatcher成一个过程而不是一个线程,那么它成为一个独立的操作系统级的过程,操作系统可以独立地调度等系统调用只会阻止过程,而不是主要的一个。


除了是Python自动当你生成一个进程关闭STDIN 。

所以,你需要有另外一个在主过程中的队列中的生产者,只有消费者。 这也是一个简单的适应-不启动生产者(InputCatcher)运行直到所有的消费过程中已经产生了。 这涉及到移动线:

ic.start()

两个循环之下。 但是,在这种情况下,没有必要为将要在所有中背景 - 它不与其他事物同时运行。 所以,你可以忘掉完全是InputCatcher类,并只写你这样的代码:

for usb in usbs:
    usb.daemon = True
    usb.start()

while True:
    input_queue.put(input())

您可能还需要考虑一个特定的输入 - 说,空字符串 - 结束程序。 在其主运行输入使这真的只是停止循环容易:

while True:
    data = input('Type data; or enter to exit: ')
    if not data:
        break
    input_queue.put(data)


Answer 2:

self.input_queue.put(input())

这意味着:要求用户进行输入,现在 ,不是把任何用户输入是伊诺的队列。

看起来应该是这样的

self.input_queue.put(lambda: input())

看起来你省略了从你的代码中的管道,因此它不能运行为是。



文章来源: input() is blocking the use of processes