我在使用python線程時遇到了一些麻煩。我正在編寫一個軟件包,用於繪製從多個設備接收的數據。我有一個繪圖線程,它會在數據收到來自所有設備的一組數據以及每個設備的數據檢索線程後繪製數據。應用程序不斷繪製數據(與從設備中檢索數據一樣快),直到用戶點擊按鈕。我有一個threading.Event()self.stop_thread被頻繁檢查以退出線程循環。根據我的調試器和threading.active_count(),線程碰到檢查點,跳出循環,但仍然「運行」。有誰知道爲什麼會發生這種情況,我該如何讓它停止?我需要知道在移動到應用程序的另一個功能之前,這些線程已經消失。以下三種方法是問題出現的地方。python線程在目標方法執行完畢後沒有終止
# initalizes startup settings, starts a thread to carry out
# plotting and a seperate thread to carry out data retrieval
def start_plot_threads(self):
if not self.abstraction.connected:
self.connect_to_device()
if not self.abstraction.connected:
return
self.stop_thread.clear()
self.pause_thread.clear()
for device in self.devices:
device.pause_thread.clear()
device.stop_thread.clear()
device.change_units.set()
self.presentation.enable_derivative()
self.presentation.show_average_button.SetValue(False)
self.presentation.show_average_button.Disable()
self.abstraction.multi_plot_data = {}
try:
if self.plot_thread.is_alive():
return
except Exception:
pass
self.plot_thread = Thread(target=self.plot_data)
self.plot_thread.daemon = True
self.plot_thread.start()
for device in self.devices:
thread = Thread(target=self.retrieve_data,
kwargs={'device': device},
name="Data Retrieval Thread %s" % device.instr_id)
thread.daemon = True
thread.start()
# waits for plot data to be thrown on a thread safe queue by the data
# retrieval thread and plots it. data comes in as a tuple of the form
# (y_data, label, x_data)
def plot_data(self):
multiplot = False
if len(self.devices) > 1:
multiplot = True
plot_data = []
while not self.stop_thread.is_set():
try:
data = self.plot_data_queue.get()
except Empty:
pass
else:
if multiplot:
scan = {}
scan['y_data'] = [data[0]]
scan['labels'] = [data[1]]
scan['x_data'] = data[2]
plot_data.append(scan)
if len(plot_data) == len(self.devices):
self.presentation.plot_multiline(plot_data, average=False)
self.abstraction.multi_plot_data = plot_data
plot_data = []
else:
self.presentation.plot_signal(data[0], data[1])
# the intent is that the data retrieval thread stays in this loop while
# taking continuous readings
def retrieve_data(self, device):
while True:
if device.stop_thread.is_set():
return
while device.pause_thread.is_set():
if device.stop_thread.is_set():
return
sleep(0.1)
y = self.get_active_signal_data(device)
if not y:
return
self.plot_data_queue.put(
(y, device.name, device.x_data))
self.abstraction.y_data = [y]
try:
self.update_spectrum(device)
except DeviceCommunicationError, data:
self.presentation.give_connection_error(data)
self.presentation.integ_time = device.prev_integ
對於方法中額外的體積,我表示歉意。他們是直接從我的代碼庫。
爲什麼你設置'守護= TRUE;你的主題? –
我設置了daemon = True,以便在主線程終止時應用程序將退出。我並不擔心數據丟失或者線程是否完成了他們的任務。我只需要確保線程在移動到應用程序的另一個函數之前就被終止了。 – jgramse