目标方法执行完毕后,python线程没有终止

时间:2015-06-09 23:03:10

标签: python multithreading

我遇到了一些python线程的麻烦。我正在编写一个软件包,用于绘制从多个设备接收的数据。我有一个绘图线程,一旦从所有设备接收到一组数据,就绘制数据,并为每个设备提供数据检索线程。应用程序连续绘制数据(尽可能快地从设备检索数据),直到用户点击按钮。我有一个threading.Event()self.stop_thread经常被检查以退出线程循环。线程点击检查,突破循环,但仍然根据我的调试器和threading.active_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

我为方法中的额外批量道歉。它们直接来自我的代码库。

1 个答案:

答案 0 :(得分:0)

你的线程继续运行的原因是未知的 - device.stop_thread.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() 

加入将等待线程完成,然后继续。

Python文档: https://docs.python.org/2/library/threading.html