Python:将GUI进程与核心逻辑进程分离

Python:将GUI进程与核心逻辑进程分离,python,user-interface,multiprocessing,user-experience,Python,User Interface,Multiprocessing,User Experience,我正在开发一个用于处理计算机模拟的界面,我也在为它开发一个GUI。(核心逻辑本身不需要GUI。)我使用的GUI工具包是wxPython,但我认为我的问题很一般,不需要依赖它 GUI当前的工作方式是,它在与GUI相同的进程和线程上启动核心逻辑包(称为garlicsim)。这是可行的,但我理解这是一个有问题的方法,因为如果核心逻辑需要做一些硬计算,GUI将挂起,我认为这是不可接受的。 我该怎么办 我听说可以选择在独立于GUI的进程上启动核心逻辑。这听起来很有趣,但我对此有很多问题 我是否使用多处理包

我正在开发一个用于处理计算机模拟的界面,我也在为它开发一个GUI。(核心逻辑本身不需要GUI。)我使用的GUI工具包是wxPython,但我认为我的问题很一般,不需要依赖它

GUI当前的工作方式是,它在与GUI相同的进程和线程上启动核心逻辑包(称为
garlicsim
)。这是可行的,但我理解这是一个有问题的方法,因为如果核心逻辑需要做一些硬计算,GUI将挂起,我认为这是不可接受的。 我该怎么办

我听说可以选择在独立于GUI的进程上启动核心逻辑。这听起来很有趣,但我对此有很多问题

  • 我是否使用
    多处理
    包或
    子流程
    包启动新流程
  • 如何从GUI过程轻松访问模拟数据?毕竟,它将存储在另一个进程上。用户应该能够轻松顺利地浏览模拟的时间线。如何做到这一点

  • 您可能会在这里找到一些灵感:,但是它是针对多线程的,而不是针对多处理的

    基本思想

    • 对于多线程:使用事件队列在GUI和处理线程之间进行通信
    • 对于多进程:可以使用子进程包,并使用子进程的stdin/stdout与之通信。为此,您需要一个命令行api,但它最终会派上用场,因为您可以进行独立于gui的单元测试
    您甚至可以通过套接字驱动i/o通信,这将使模拟的网络管理变得简单


    编辑:我刚刚看到了你提到的2.6版本的新多处理软件包。看起来是个不错的选择,您可以使用队列在进程之间进行通信。这是一个更紧密的耦合,您可以根据需要进行选择。

    不幸的是,尽管GUI的选择不会影响答案,但解决此问题的最佳方法在很大程度上取决于您的模拟数据到底在做什么

    例如,如果它生成顺序数据,那么它可以通过线程安全或进程安全队列将其提供给GUI。但是,如果它改变了整个数据,并且您的GUI需要能够在任何给定的时间查看快照,那么通过沿队列发送整个状态来解决这一问题可能成本太高,并且可能需要一种互斥方式来共享对数据结构的访问。因此,对数据所做工作的性质在这里至关重要


    至于使用多处理还是子处理,这取决于是否有一个完全独立的程序来处理数据。前者用于以多线程的方式进行多处理—它是在多个进程中运行的同一程序的不同部分。后者是指一个程序想要运行另一个程序(可能是该程序的副本,但通常不是)。同样,很难知道哪种方法最适合您的具体情况,尽管听起来您可以将核心逻辑作为命令行应用程序,并通过管道、套接字等进行通信。

    来回答具体问题

    “我是否使用
    多处理
    包或
    子流程
    包启动新流程?”

    使用
    多处理

    “如何从GUI流程轻松访问模拟数据?”

    您没有访问仿真过程对象的权限,如果这是您所要求的,则仿真是一个单独的过程。您可以启动它,停止它,最重要的是,还可以通过发送到模拟器的命令队列发出请求

    “用户应该能够轻松顺利地浏览模拟的时间线。如何做到这一点?”

    这只是设计。单进程、多进程、多线程对这个问题没有任何影响

    每个模拟必须有一些参数,必须启动,必须生成日志(或时间线)。无论使用哪个库启动和停止模拟,都必须执行此操作

    模拟的输出——输入到GUI——可以通过一百万种方式完成

    • 数据库。模拟时间线可以插入到SQLite数据库中,并由GUI查询。这并不是很好,因为SQLite没有真正聪明的锁定。但它确实有效

    • 文件。模拟时间线将写入文件。GUI读取文件。这真的,真的很好

    • 请求/答复。模拟有多个线程,其中一个线程将命令排在队列中,并通过以下方式进行响应:例如,将时间线发送回当前时刻,或停止模拟或更改参数并重新启动模拟


    最简单的方法是在单独的线程中启动计算,并使用
    队列
    对象在该线程和GUI之间通信数据。这些都是完全安全的,对于线程间的通信非常方便


    其他解决方案更为复杂-您可能最终在一个完全独立的“服务器”进程中运行模拟,并通过主GUI与套接字通信。

    多处理或Pyro与分布式数据对象通信

    您的模拟将分布式对象提供给GUI,GUI对其进行操作并读取其属性


    这两个库都可以在网络上轻松地扩展,但可以在本地运行。当您的模拟开始处理太多的数字时,请添加更多的模拟服务器,以提供更多的分布式对象。

    通过“子流程”包,我认为您的意思是“子流程”,对吗?