在我创建的jythongui中,我有一些长期的流程,这些流程必须在给定的按钮按下或其他事件时发生。在
在这种情况下,最好的选择是在事件发生时创建一个单独的线程来运行被调用的方法/函数。在
最好的办法是什么?导入线程并有一个类,我在actionPerformed时初始化并运行它?使用invokelater?似乎有很多方法可以做到这一点,但是在jythonswing环境中工作得最好,并且是“最快”的吗?在
start = JButton( "Analyze", actionPerformed = self.do_analysis )
def do_analysis(self):
...
Large Time Consuming Task
...
我不能百分之百地肯定jython也有同样的问题,但是在C Python中,您会遇到GIL或全局解释器锁的问题。这意味着当后台线程正在运行时,GUI线程无法启动(即使它排队在另一个内核上运行)。你点击一个按钮,什么也没有发生:(
为了解决这一问题,我将长时间运行的流程拆分为可以在事件上运行的短步骤,并将事件排队以在当前步骤结束时启动下一步。如果需要的话,GUI将能够在步骤之间运行。步骤越短,GUI的响应就越快-50ms到100ms应该可以。在
这种方法有一个很好的副作用,您不需要担心线程、锁定、消息队列或其他任何事情。您可以尝试将这些添加到GUI中,但是GUI事件和线程可能会发生冲突,从而导致一些非常奇怪和难以调试的错误。在
至于“最快”,这可能是较短后台任务的最低开销。如果您创建一个新进程来运行后台任务(在Windows中开销很大),那么它将运行得更快,因为它有自己的核心,但是启动/停止开销很高。在
在这种情况下,您可以通过记住Jython运行在JVM上来获得最佳结果。因此,jythapi必须使用独立的Java线程来设置Java线程计算。如果CPU负载足够高,使用更多的内核会有所帮助,Java(jvm)将自行解决这一问题。在
在某些情况下,对于长时间运行的进程,人们使用
jstack -l
来获取正在运行的线程的nids
,然后使用taskset
来设置CPU相关性。JVMnid
是十六进制的,是与线程对应的Linux进程的PID。其他操作系统可能具有类似的功能。在一般来说,除了使Jython成为多线程之外,不需要做任何事情。如果使用Python线程模块,则无法访问完整的Java线程特性集,但它实际上使用了JVM线程。只需记住限制对全局变量的访问,否则最终将重新创建全局解释器锁。队列模块可以帮助实现这一点。在
相关问题 更多 >
编程相关推荐