python线程不是';t在目标方法完成执行后终止
我在python线程方面遇到了一些问题。我正在编写一个软件包,它可以绘制从多个设备接收到的数据。我有一个plot线程,当它从所有设备接收到一组数据时,它就会绘制数据,每个设备都有一个数据检索线程。应用程序连续绘制数据(尽可能快地从设备检索数据),直到用户点击按钮。我有一个threading.Event()self.stop_线程,它经常被检查以退出线程循环。线程通过了检查,脱离了循环,但根据我的调试器和threading.active\u count()仍在“运行”。有人知道为什么会这样吗?我怎样才能让它停止?在我转到应用程序的另一个函数之前,我需要知道这些线程已经消失了。以下三种方法是出现问题的地方python线程不是';t在目标方法完成执行后终止,python,multithreading,Python,Multithreading,我在python线程方面遇到了一些问题。我正在编写一个软件包,它可以绘制从多个设备接收到的数据。我有一个plot线程,当它从所有设备接收到一组数据时,它就会绘制数据,每个设备都有一个数据检索线程。应用程序连续绘制数据(尽可能快地从设备检索数据),直到用户点击按钮。我有一个threading.Event()self.stop_线程,它经常被检查以退出线程循环。线程通过了检查,脱离了循环,但根据我的调试器和threading.active\u count()仍在“运行”。有人知道为什么会这样吗?我怎
# 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
我为方法中的额外体积道歉。它们直接来自我的代码库。您的线程继续运行的原因未知-
设备。停止线程。is_set():
(设置的目的是什么??)
但是,您可以通过在每个线程上保留一个处理程序(通过将每个线程对象附加到列表中)来保证所有线程都已停止,并且一旦启动了所有线程,就可以继续执行thread.join()
threads = []
for job in batch:
thr = threading.Thread(target=do_job, args = (job))
thr.start()
threads.append(thr)
#join all the threads
for thr in threads:
thr.join()
Join将等待线程完成后再继续
Python文档:
stop_thread.set()在用户单击应用程序中的多个按钮之一时调用。它被正确设置、正确检查,并且目标方法的执行被正确返回。我尝试了thread.join()(我曾经将线程保存在一个列表中),但它永远停留在对join()的阻塞调用中。线程没有执行任何任务,因为它们已经离开了目标方法。他们只是在跑。。。永远。。。我也不知道为什么。thread.join()将执行您期望的操作,因此您应该返回到该代码。我敢打赌,你的问题主要在于你需要知道的是,如果你的代码中没有执行中断,其他线程将完全(或几乎)被阻止运行。如果您在其他地方的读循环中,请执行time.sleep-这将给其他线程一个运行的机会。谢谢John。不确定为什么它以前不工作,但thread.join()现在似乎正在工作。为什么要为线程设置
daemon=True
?我设置daemon=True,以便在主线程终止时退出应用程序。我不担心数据丢失,也不担心线程是否完成了任务。我只需要确保在转到应用程序的另一个函数之前终止线程。