所以我正在開發一個 GUI ( PyQt5 ) 并且我是多執行緒的,以便能夠同時進行資料采集和實時繪圖。
長話短說,除了停止處理資料采集的執行緒外,所有作業都很好,該執行緒連續回圈并呼叫PySerial來讀取 com 埠。當按下 GUI 上的按鈕時,我想打破執行緒內的 while 回圈,以停止讀取 com 埠并允許安全地關閉 com 埠。
目前,我嘗試過的任何方法都沒有設法優雅地退出執行緒內的 while 回圈,這會導致PySerial庫和關閉的 com 埠/嘗試在執行緒中讀取的各種錯誤。這是我嘗試過的:
- 使用類變數 (
self.serial_flag) 并在按下按鈕時更改其狀態。然后執行緒回圈如下所示:while self.serial_flag: - 使用全域變數(
serial_flag = False在腳本頂部)。global serial_flag在執行緒函式和相同條件的頂部定義:while serial_flag: - 使用共享記憶體變數: ,然后在回圈檢查中
from multiprocessing import Value定義thenserial_flag = Value('i', 0)while serial_flag.value == 0: - 用于
threading.Event設定事件并將其用作中斷條件。定義:serial_flag = threading.Event()并在執行緒內部while回圈:if serial_flag.is_set(): break
這些似乎都不能打破while回圈,我保證我已經完成了研究這類事情的解決方案的功課——我覺得我的多執行緒應用程式做錯了一些基本的事情。以下是呼叫/處理執行緒的 GUI 部分(我最近嘗試使用 threading.Event):
import threading, queue
serial_flag = threading.Event()
def serial_run_data(self):
cntr = 0
while True:
if serial_flag.is_set():
print("flag was set")
break
value = self.ser.read_until(self.EOL) # old EOL: \r\n, new: o\i
if len(value) == 21 and self.EOL in value:
self.queueRaw.put_nowait(value)
else:
print(value)
cntr = cntr 1
if cntr == 50:
self.data_ready = True
cntr = 0
def start_plot(self): # Start/ Stop Button
# Start Button
if self.start_button.text() == 'START':
self.serial_setup()
if not self.error:
self.serial_flag = True
self.t = threading.Thread(target=self.serial_run_data)
self.t.start()
self.timer.start()
self.start_button.setText('STOP')
# Stop Button
elif self.start_button.text() == 'STOP':
if not self.error:
self.serial_flag = False
serial_flag.set()
self.timer.stop()
print(self.t.is_alive())
self.ser.close()
self.start_button.setText('START')
感謝您提供任何反饋(如果我提供的內容不充分,我將制作一個可重復性最低的示例)。干杯!
uj5u.com熱心網友回復:
嘗試通過以下方式啟動執行緒,將threading.Event物件作為引數傳遞給 :serial_run_data
self.t = threading.Thread(target=self.serial_run_data, args=(serial_flag,))
并將事件添加到serial_run_data方法的引數中。在類級別上定義threading.Event可能會更好,因為它把它放在一個更窄的范圍內(我假設你洗掉了其余的類代碼,因為你self作為方法的引數離開了)。
設定事件現在應該打破回圈。
編輯 (提供附加資訊)
出現此問題是因為您正在關閉串行埠而不等待執行緒終止。盡管您設定了事件,但可能無法訪問該部分代碼,因為從串行埠讀取仍在發生。關閉串口時,串口庫出現錯誤。
您應該等待執行緒終止,然后關閉埠,您可以通過添加
self.t.join()
之后serial_flag.set()。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/424564.html
標籤:Python 多线程 pyqt5 python-多线程 pyserial
上一篇:訪問當前PowerShell實體
