【发布时间】:2011-05-18 18:26:56
【问题描述】:
我正在自学一些 Python OOP,并且我创建了一个简单的 GUI,它使用 Popen 在后台启动许多脚本。我需要始终确定这些脚本是否处于活动状态,我打算使用循环。
但是我怎样才能让一个循环始终在后台运行,而不影响用户使用 GUI 的能力?
【问题讨论】:
标签: python loops background subprocess
我正在自学一些 Python OOP,并且我创建了一个简单的 GUI,它使用 Popen 在后台启动许多脚本。我需要始终确定这些脚本是否处于活动状态,我打算使用循环。
但是我怎样才能让一个循环始终在后台运行,而不影响用户使用 GUI 的能力?
【问题讨论】:
标签: python loops background subprocess
您必须在后台运行一个线程。线程只是与任何其他线程同时运行的一组代码。例如,python 程序是一个线程,任何时候只能发生一个动作,这就是为什么您会看到带有无限循环和 gui 的滞后。如果您创建一个新线程,但 gui 将在一个线程中运行,而循环在一个单独的线程中运行。这是一个完美的世界。
进一步了解 python 中的 google threading,但这里有一些链接: http://www.prasannatech.net/2008/08/introduction-to-thread-programming.html http://www.wellho.net/solutions/python-python-threads-a-first-example.html http://www.devshed.com/c/a/Python/Basic-Threading-in-Python/
祝你好运
【讨论】:
请注意,python 不支持多线程执行。当 python 运行时,在任何给定时间只有 1 个线程在运行。但是,您仍然必须确保您的数据不受多次访问的影响(即一个线程开始做某事,正在中断,另一个线程开始执行并开始做其他事情,随之而来的是欢闹)
在 gui 中编码时,您不应该(并且可能不会,因为它经常导致崩溃)从多个线程操作您的小部件。大多数 GUI 提供了一种将“任务”发布到运行 GUI 的线程的方法)这可能很乏味,但它是唯一可行的方法。例如:wxPython 提供了一个wx.CallAfter 函数。
尽可能尝试分配您的locks(以防止线程同时接触共享数据)和condition objects(用于向一个线程发出信号以继续从另一个线程处理某事)在您启动线程之前,在您的构造函数中:
import threading
class(object):
def __init__(self):
self._lock = threading.Lock()
self._cond = threading.Condition(self._lock) # conditions are associated with locks
并准备好看到这个构造:
def myMethod(self):
self._lock.acquire()
try: # or with if you prefer
# do my stuff
# pack up my data
def myFunc():
# post updates to widgets
finally:
self._lock.release()
wx.CallAfter(myFunc)
【讨论】:
_thread, queue, operator, tkinter.filedialog, tkinter.messagebox, tkinter.ttk。鉴于代码底部列出的包装小部件的示例,该代码易于扩展。您可以查看整个配方以获取完整的使用示例。