如何在后台运行无限循环并停止它?

2024-10-02 18:27:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我的问题是:使用Tkinter,我想单击一个按钮并启动一个python脚本。 这个python脚本现在是一个导入到主脚本中的模块(我不知道这是否是最好的方法)。 此脚本应在后台运行。它有一个方法可以让它退出。我怎么称呼它? 我想传递一个旗帜或其他东西到模块,但我不知道怎么做。在

现在,我这样称呼我的代码:in图形用户界面.py在

import sniffer_wideband_v09
from Tkinter import *
root = Tk()
def handle_click():
    global t
    global stop_flag
    stop_flag = 0

    def callback():
        sniffer_wideband_v09.main(sampling_rates, center_frequencies, gains, file_dir, files_names) 
    t = Thread(target=callback)
    t.start()
root.mainloop()

我想调用sniffer_wide band_v09.py中的quiting()方法。或者向我的模块传递一个标志来停止无限循环。 之后,我需要将所有这些绑定到Tkinter按钮上。在

我对这个问题做了一些研究,发现:

Is there any way to kill a Thread in Python? 随着 How to run a function in the background of tkinterHow to run and stop an infinite loop in a python thread

第一个是有希望的,但我不完全理解,我正在努力。在

注意:我直接用我的shell运行它/图形用户界面.py我使用的是Ubuntu,而不是windows(我认为它可以改变一些处理多线程的方式)。在

感谢阅读,任何提示或帮助将不胜感激。如果我在同一时间内找到响应,我会发布我的代码。在

编辑:提供有关线程中启动的脚本的更多信息:(它是一个GNURadio脚本)

^{pr2}$

Tags: 模块to方法代码inpyimport脚本
3条回答

因为Tkinter gui应用程序和主应用程序之间没有交互 我推荐您从sniffer_wideband_09模块调用的代码 要使用多重处理:

import sniffer_wideband_v09
import multiprocessing
from Tkinter import *
root = Tk()
def handle_click():
    global t

    t = multiprocessing.Process(target=sniffer_wideband_v09.main, args=(sampling_rates, center_frequencies, gains, file_dir, files_names))
    t.start()
root.mainloop()

当您想停止此过程时,只需调用t.terminate()。阅读有关多处理模块文档的更多信息。在

我花了几个小时试图解决您的问题,以供我自己借鉴,使用线程,而几个无响应的ui后来得到这样的结果:TkInter不是线程安全的,从 tkinter tkMessageBox not working in thread。在

GUI工具箱通常是事件驱动的。这意味着程序在循环中运行,处理事件(鼠标移动、单击、击键、计时器等)。在

在事件驱动程序中运行长时间运行的计算通常有三种方法

  • 计时器和回调
  • 分离过程
  • 螺纹

第一个解决方案相对简单。你设置了一个计时器。此计时器将在用完后生成事件或调用回调函数(取决于工具箱)。您可以在回调中做一些工作,保存计算状态,可能更新一个进度指示器,重新启动计时器并退出回调。这与GUI很好地融合在一起,但是需要对代码进行结构化,以便将工作分成小块。如果回调花费的时间太长,事件处理将受到影响,GUI将感觉不响应。回调的运行时间不应超过10到100毫秒。这种方法不能利用现代CPU中普遍存在的多核。在

第二个解决方案是启动一个单独的过程,如mguijarr所示。在CPython上,这是一个非常好的解决方案,因为这根本不会影响GUI,而且您仍然可以使用各种方法(信号、套接字、共享内存、消息队列)与外部程序通信。这将利用多核的优势。使用multiprocessing.Pool您甚至可以将工作分配到所有可用的核心上。在

另一方面,在这种情况下,线程不是CPython中的最佳解决方案。全局解释器锁(“GIL”)限制CPython解释器,以便一次只能有一个线程执行Python字节码。这最初是为了简化内存管理。因此,即使您使用一个单独的线程进行计算,您仍然可以耗尽GUI的处理器时间并使其无响应。你必须用锁保护多个线程使用的数据。对于大多数GUI工具包,只有一个线程可以调用工具箱函数。因此,您不能从第二个线程更新进度指示器。在

相关问题 更多 >