有没有办法在 Python 中进行长时间的处理循环而不用 TideSDK 冻结 GUI?或者我只需要使用线程......
谢谢。
TideSDK 这里并没有什么特别之处——这是任何围绕事件循环构建的程序的普遍问题,这意味着几乎所有的 GUI 应用程序和网络服务器等等。
共有三种标准解决方案:
将长任务分解成一堆小任务,每个小任务都安排下一个运行。
每隔一段时间让任务回调到事件循环。
并行运行任务。
对于第一个解决方案,大多数基于事件的框架都有类似doLater(func)
or的方法setTimeout(func, 0)
。如果没有,他们至少必须有一种将消息发布到事件循环队列的方法,并且您可以很容易地doLater
围绕它构建一个。这种 API 在类 C 语言中使用起来可能很糟糕,并且在 JS 中有点令人讨厌,只是因为奇怪的 this/范围规则,但在 Python 和大多数其他动态语言中它几乎是无痛的。
由于 TideSDK 是围绕浏览器 JS 引擎构建的,它几乎肯定会提供第一个解决方案。
第二种解决方案仅对围绕协作线程或显式协程构建的框架才有意义。然而,一些传统的单线程框架,如经典 Mac(以及因此,现代 Win32 和一些跨平台框架,如 wxWindows)使用它来运行后台作业。
第一个问题是你必须小心处理重入(至少wx
有SafeYield
一点帮助),否则你可能会遇到许多与线程相同类型的问题——或者更糟糕的是,一切似乎都正常,除了在大量使用下,您偶尔会因无限递归而导致堆栈崩溃。另一个问题是,它只有在一次只有一个繁重的后台任务时才能真正发挥作用,因为它不能很好地工作
如果你的框架有办法做到这一点,它会有一个类似yieldToOtherTasks
or的函数processNextEvent
,你所要做的就是确保每隔一段时间调用一次。(但是,如果还有doLater
,则应首先考虑。)如果没有这样的方法,则此解决方案不适合您的框架。
threading.Thread
第三种解决方案是通过或分拆任务multiprocessing.Process
。
这种并行性的问题在于,您必须想出某种方法来安全地发出信号,并安全地共享数据。一些事件循环框架具有线程安全的“doLater”或“postEvent”方法,如果您需要的唯一信号是“任务完成”并且您需要共享的唯一数据是任务启动参数和返回值,那么一切都是简单的。但一旦这还不够,事情就会变得非常复杂。
此外,如果您有数百个长时间运行的任务要运行,您可能不希望每个任务都有一个线程或进程。事实上,你可能想要一个固定大小的线程或进程池,然后你必须将你的任务分解成足够小的子任务,这样它们就不会互相饿死,所以实际上你正在做所有无论如何,解决方案#1的工作。
However, there are cases where threads or processes are the simplest solution.