Handling Processing-Intensive Event-Actions in Jython
我有一些长期的过程,这些过程必须在我创建的Jython GUI中给定的按钮按下或其他事件下发生。
在这种情况下,最好的选择似乎是创建一个单独的线程,以便在事件发生时运行被调用的方法/函数。
做这个的最好方式是什么? 导入线程,并拥有一个在actionPerformed时初始化并运行的类? 使用invokelater吗? 似乎有很多方法可以解决此问题,但是在Jython-Swing环境中是否会表现最佳并成为"最快"的?
1 2 3 4 5 6 | start = JButton("Analyze", actionPerformed = self.do_analysis ) def do_analysis(self): ... Large Time Consuming Task ... |
我不是100%肯定jython会遇到同样的问题,但是在C Python中,您会遇到GIL或Global Interpreter Lock的问题。这将意味着,当您的后台线程正在运行时,GUI线程将无法启动(即使已排队等待在另一个内核上运行)。您单击一个按钮,没有任何反应:(
为了解决这个问题,我将长时间运行的流程分为可以在事件上运行的几个步骤,然后将事件排队,以便在当前步骤结束时开始下一步。然后,如果需要,GUI将能够在步骤之间运行。您执行的步骤越短,GUI的响应就越快-50ms至100ms应该可以。
这种方法具有很好的副作用,您无需担心线程,锁定,消息队列或其他任何问题。您可以尝试将它们添加到GUI,但是GUI事件和线程可能会发生冲突,从而导致一些非常奇怪且难以调试的错误。
至于"最快",这对于较短的后台任务来说可能是最低的开销。如果您创建一个新进程来运行后台任务(Windows中的开销非常大),则由于它具有自己的核心,因此它将运行得更快,但是启动/停止开销很高。
在这种情况下,通过记住Jython在JVM上运行,您将获得最佳结果。 Jython拥有对Java类的完全访问权限,因此请使用Java线程API来设置单独的计算线程。而且,如果CPU负载足够高,以至于使用更多的内核会有所帮助,那么Java(jvm)将自行解决。
在某些情况下,随着进程的长时间运行,人们使用
通常,除了使Jython多线程外,没有必要做任何其他事情。如果使用Python线程模块,则无权访问完整的Java线程功能集,但实际上使用了JVM线程。只要记住要限制对全局变量的访问,否则最终将重新创建全局解释器锁。队列模块可以提供帮助。