问题
I have a python application that is being built to run some tests that involves using a Null Modem USB-to-USB (Currently using an emulator on PC) to send serial data from one USB port to another. I have written a serial listener as follows:
import serial
import threading
from queue import Queue
class SerialPort(object):
def ___init__(self, timeout=None):
self.ser = serial.Serial(baud=_, stopbits=_, ... timeout=timeout)
self.out_q = Queue()
self.in_q = Queue()
self.THREAD = None
def setup(self, com):
self.ser.port = com
self.ser.open()
def run(self):
self.THREAD = threading.Thread(target=self.listen, args=(self.out_q, self.in_q,))
self.THREAD.start()
def listen(self, in_q, out_q):
while True:
if not in_q.empty():
# This code is never reached, even though it should be
message = in_q.get()
if message == 'DIE':
break
else:
self.ser.write(message)
def send_command(self, command):
self.in_q.put(command)
class GUI(object):
def __init__(self):
self.POWER = False
self.server_port = SerialPort(timeout=0.1)
self.client_port = SerialPort(timeout=0.1)
#etc etc Tkinter stuff and things
def on_power_button_click(self):
# Tkinter Button already made, know the button works as expected
self.POWER = not self.POWER
if self.POWER:
self.server_port.setup('COM5')
self.client_port.setup('COM6')
self.server_port.run()
self.client_port.run()
else:
self.server_port.send_command('DIE')
self.client_port.send_command('DIE')
time.sleep(0.3)
self.server_port.ser.close()
self.client_port.ser.close()
my_example_problem = GUI()
# Creates threads and 'turns on' the application
my_example_problem.on_power_button_click()
# Should Turn off the application but doesn't
my_example_problem.on_power_button_click()
Things turn on just fine, but whenever they are turned off, the 'DIE' command never gets registered in listen(), and in_q.empty() is stuck as being False, and I can't figure out why. I'm wondering if it might be a scope problem, however I have another application that is written with the exact same scopes but only uses one thread and works just fine, and from my understanding a Python Queue works similarly to a C queue with a pointer to the starting memory block so scope shouldn't matter.
回答1:
The problem is that your target function listen
has signature ..., in_q, out_q
accepting input queue first, then output queue - but the Thread
(within run()
function) is started with wrong order of arguments:
... , args=(self.out_q, self.in_q,)
Change arguments/queues order on Thread instantiation:
self.THREAD = threading.Thread(target=self.listen, args=(self.in_q, self.out_q,))
来源:https://stackoverflow.com/questions/57098465/python-multithreaded-queue-remaining-empty