Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python线程不是';t在目标方法完成执行后终止_Python_Multithreading - Fatal编程技术网

python线程不是';t在目标方法完成执行后终止

python线程不是';t在目标方法完成执行后终止,python,multithreading,Python,Multithreading,我在python线程方面遇到了一些问题。我正在编写一个软件包,它可以绘制从多个设备接收到的数据。我有一个plot线程,当它从所有设备接收到一组数据时,它就会绘制数据,每个设备都有一个数据检索线程。应用程序连续绘制数据(尽可能快地从设备检索数据),直到用户点击按钮。我有一个threading.Event()self.stop_线程,它经常被检查以退出线程循环。线程通过了检查,脱离了循环,但根据我的调试器和threading.active\u count()仍在“运行”。有人知道为什么会这样吗?我怎

我在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,以便在主线程终止时退出应用程序。我不担心数据丢失,也不担心线程是否完成了任务。我只需要确保在转到应用程序的另一个函数之前终止线程。