擅长:python、mysql、java
<p>GUI工具箱通常是事件驱动的。这意味着程序在循环中运行,处理事件(鼠标移动、单击、击键、计时器等)。在</p>
<p>在事件驱动程序中运行长时间运行的计算通常有三种方法</p>
<ul>
<li>计时器和回调</li>
<li>分离过程</li>
<li>螺纹</li>
</ul>
<p>第一个解决方案相对简单。你设置了一个计时器。此计时器将在用完后生成事件或调用回调函数(取决于工具箱)。您可以在回调中做一些工作,保存计算状态,可能更新一个进度指示器,重新启动计时器并退出回调。这与GUI很好地融合在一起,但是需要对代码进行结构化,以便将工作分成小块。如果回调花费的时间太长,事件处理将受到影响,GUI将感觉不响应。回调的运行时间不应超过10到100毫秒。这种方法不能利用现代CPU中普遍存在的多核。在</p>
<p>第二个解决方案是启动一个单独的过程,如mguijarr所示。在CPython上,这是一个非常好的解决方案,因为这根本不会影响GUI,而且您仍然可以使用各种方法(信号、套接字、共享内存、消息队列)与外部程序通信。这将利用多核的优势。使用<code>multiprocessing.Pool</code>您甚至可以将工作分配到所有可用的核心上。在</p>
<p>另一方面,在这种情况下,线程不是CPython中的最佳解决方案。全局解释器锁(“GIL”)限制CPython解释器,以便一次只能有一个线程执行Python字节码。这最初是为了简化内存管理。因此,即使您使用一个单独的线程进行计算,您仍然可以耗尽GUI的处理器时间并使其无响应。你必须用锁保护多个线程使用的数据。对于大多数GUI工具包,只有一个线程可以调用工具箱函数。因此,您不能从第二个线程更新进度指示器。在</p>