Приложение имеет функцию стартового моста, которая заканчивается созданием потоков, как показано ниже:
Код: Выделить всё
self.stop_event.clear()
self.read_thread = threading.Thread(target=self.read_and_send_serial_data, daemon=True)
self.read_thread.start()
self.listen_thread = threading.Thread(target=self.listen_and_forward_udp_data, daemon=True)
self.listen_thread.start()
Код: Выделить всё
def read_and_send_serial_data(self):
self.log("Serial->UDP thread started")
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while not self.stop_event.is_set():
try:
if self.serial_conn.in_waiting > 0:
data = self.serial_conn.read(self.serial_conn.in_waiting)
udp_socket.sendto(data, (self.target_ip, int(self.target_port)))
self.log(f"Sent: {data}")
except Exception as e:
self.log(f"Error: {e}")
time.sleep(self.interval)
udp_socket.close()
def listen_and_forward_udp_data(self):
self.log("UDP->Serial thread started")
listen_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
listen_socket.bind(('', int(self.listen_port)))
listen_socket.setblocking(False) # Set socket to non-blocking mode
while not self.stop_event.is_set():
try:
ready_to_read, _, _ = select.select([listen_socket], [], [], 1.0)
if ready_to_read:
data, addr = listen_socket.recvfrom(1024) # Buffer size 1024 bytes
if data:
self.serial_conn.write(data)
self.log(f"Received from {addr}: {data}")
else:
time.sleep(0.1)
except socket.error as e:
self.log(f"Error: {e}")
break
listen_socket.close()
self.log("Listening thread terminated")
Моя функция stop_bridge:
Код: Выделить всё
def stop_bridge(self):
self.stop_event.set()
if self.read_thread.is_alive():
self.log("Stopping Reading Serial Thread")
self.read_thread.join()
self.log("Thread joined.")
if self.listen_thread.is_alive():
self.log("Stopping Listening UDP Thread")
self.log("Waiting for the thread to join.")
self.listen_thread.join() # Add a timeout to join
self.log("Thread joined.")
if self.serial_conn:
self.serial_conn.close()
self.log("Bridge stopped.")
self.start_button.config(state=tk.NORMAL)
self.stop_button.config(state=tk.DISABLED)
self.status_label.config(text="Status: Not running")
Оба потока открывают сокеты и закрывают их внутри своих соответствующие функции, и я убедился, что для параметра stop_event установлено значение остановки цикла.
Кто-нибудь сталкивался с подобной проблемой или может предложить лучший подход? Есть ли лучшая библиотека потоков, которую мне следует рассмотреть, или я что-то упускаю в текущей реализации?
Заранее благодарю за любую помощь!
Подробнее здесь: https://stackoverflow.com/questions/785 ... -in-python