13

我正在开发一个用于处理计算机模拟的Python 项目,并且我也在为它开发一个 GUI。(核心逻辑本身不需要 GUI。)我使用的 GUI 工具包是 wxPython,但我认为我的问题足够笼统,不依赖于它。

GUI 当前的工作方式是在与 GUIgarlicsim相同的进程和线程上启动核心逻辑包(称为 )。这行得通,但我知道这是一个有问题的方法,因为如果核心逻辑需要进行一些硬计算,GUI 会挂起,我认为这是不可接受的。

我应该怎么办?

我听说了在与 GUI 不同的进程上启动核心逻辑的选项。这听起来很有趣,但我对此有很多疑问。

  1. 我是使用multiprocessing包还是subprocess包来启动新流程?
  2. 如何从 GUI 过程轻松访问模拟数据?毕竟,它将被存储在另一个进程中。用户应该能够轻松流畅地浏览模拟的时间线。如何才能做到这一点?
4

5 回答 5

6

您可能会在这里找到一些灵感:http ://wiki.wxpython.org/LongRunningTasks ,但它适用于多线程,而不是多处理。

基本思想

  • 对于多线程:使用事件队列在 GUI 和处理线程之间进行通信。
  • 对于多处理:可能使用subprocess包,并使用子进程的stdin/stdout与其通信。为此,您需要一个命令行 api,但它最终会派上用场,因为您可以进行与 gui 无关的单元测试。

您甚至可以通过套接字驱动 i/o 通信,这将使模拟的网络管理变得容易。

编辑:我刚刚看到你提到的 2.6-new多处理包。似乎是一个不错的选择,然后您可以使用队列在进程之间进行通信。这是一个更紧密的耦合,您可以根据自己的需要进行选择。

于 2009-12-25T14:09:54.587 回答
2

回答具体问题。

“我是使用multiprocessing包还是subprocess包来启动新流程?”

利用multiprocessing

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

您无权访问模拟过程对象,如果这是您所要求的模拟是一个单独的过程。您可以启动、停止它,并且——最重要的是——通过进入模拟器的命令队列发出请求。

“用户应该能够轻松流畅地浏览模拟的时间线,这怎么做?”

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

每个模拟都必须有一些参数,它必须开始,它必须产生一个日志(或时间线)。无论您使用什么库来启动和停止模拟,都必须这样做。

模拟的输出——输入到你的 GUI——可以用一百万种方式完成。

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

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

  • 请求/回复。模拟有多个线程,其中之一是使命令出列并通过(例如)将时间线发回当前的响应,或者停止模拟或更改参数并重新启动它。

于 2009-12-25T14:43:30.960 回答
2

Queue在这里可以为您工作的最简单的方法是在单独的线程中启动计算,并使用对象在该线程和 GUI 之间传递数据。这些对于线程间通信是完全安全且非常方便的。

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

于 2009-12-25T15:00:20.267 回答
1

不幸的是,虽然你是对的,GUI 的选择不会影响答案,但解决这个问题的最佳方法很大程度上取决于你的模拟数据到底在做什么。

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

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

于 2009-12-25T14:40:55.630 回答
0

具有分布式数据对象的 Mutiprocessing 或 Pyro。

http://pyro.sourceforge.net/

您的模拟向 GUI 提供分布式对象,GUI 操作它们并读取它们的属性。

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

于 2010-01-04T21:06:27.160 回答