我在多处理方面遇到问题。如果我正在等待线程中的输入,则进程不会启动。
将输入放入后台队列的类:
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):
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()
最佳答案
当你调用input
时,它会阻塞整个Python进程,而不仅仅是它运行的线程。发生这种情况是因为从STDIN读取,就像从任何其他类似文件的对象读取一样,涉及到阻塞系统调用 - 也就是说,等待用户输入的输入阻塞发生在操作系统级别,而不是在 Python 自己的线程管理代码内。 Python 线程对于操作系统进程调度程序来说本质上是不可见的,因此 Python 本身会被阻塞。
解决此类阻塞问题的常用方法是使用进程而不是线程。如果将 InputCatcher 设为进程而不是线程,那么它就会成为操作系统可以独立调度的单独操作系统级进程,因此系统调用只会阻塞该进程,而不是主进程。
<小时/>异常(exception),Python 自动 closes STDIN when you spawn a process 。
因此,您需要在主进程中拥有队列的生产者,而在另一个进程中仅拥有消费者。这也是一个简单的调整 - 在所有消费者进程生成之前,不要启动生产者 (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)
关于python - input() 阻塞进程的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23081060/