当用户启动模拟并定义初始状态时,我希望程序在后台持续渲染模拟,而用户可以在程序中进行其他操作,就像YouTube样式的进度条:只能播放已经渲染过的部分。
我应该使用多个进程还是多个线程?人们告诉我要使用包,我查看了它,看起来不错,但我也听说进程不能像线程那样共享很多信息(我认为我的程序需要共享很多信息)。此外,我还听说过Stackless Python:这是另一个选择吗?我一点都不清楚。
请给予建议。
"我查看了一下,看起来不错,但我也听说进程与线程不同,不能共享很多信息..."
这只是部分正确的。
线程是进程的一部分--线程可以轻松地共享内存。这既是帮助也是问题--两个没有考虑彼此的线程可能会覆盖内存并创建严重的问题。
然而,进程通过许多机制共享信息。Posix管道(a | b
)意味着进程a和进程b共享信息--a写入它,b读取它。这对于许多事情非常有用。
操作系统将尽快将您的进程分配给每个可用的核心。这对于许多事情非常有用。
无栈Python与此讨论无关--它更快,并具有不同的线程调度。但我认为线程不是最佳路线。
"我认为我的程序需要共享很多信息。"
您应该首先解决这个问题。然后,确定如何围绕信息流构建进程结构。 "管道"非常容易和自然;任何shell都可以轻松创建管道。
"服务器"是另一种架构,其中多个客户端进程获取和/或将信息放入中央服务器。这是共享信息的好方法。您可以使用WSGI参考实现来构建一个简单可靠的服务器。
更新
深入分析
如果你需要调用需要较长时间才能返回的C例程,且该例程不释放锁,则使用多线程可能不是一个好选择,这时可以考虑使用无栈协程。
如果CPU性能受到非常严重限制,并且需要最大的响应能力,则使用多进程。
不要使用无栈协程,我曾经遇到过它导致程序崩溃的情况,而且除非你正在使用数百个或更多的线程,否则线程几乎与之等效。
一个进程有自己的内存空间,这使得共享信息更加困难,但也使程序更安全(不需要显式同步)。话虽如此,进程可以以只读模式共享相同的内存。
线程更容易创建或销毁,但它与同一进程中的其他线程共享内存是主要区别。这有时是有风险的,在进程崩溃时将会杀死所有线程。
使用多个进程而不是多个线程的一个优点是更容易将程序扩展到通过网络协议通信的多台机器上运行。
例如,您可以在8台双核机器上潜在地运行16个进程,但在四核机器上最多只能从4个线程中获益。如果需要通信的信息量较低,则多进程可能更合理。
至于您所描述的YouTube风格,我会建议使用多进程。如果您遵循MVC方法,您的GUI不应该包含模型(计算结果)。使用多进程,您可以与工作管理器通信,该管理器可以报告哪些数据已经可用。
由于全局解释器锁(GIL)的存在,CPython多线程无法同时执行:链接文本。
我认为线程仍然可以提升应用程序的性能,例如一个线程可能会在I/O上阻塞,而另一个线程则可以执行一些工作。
如果您从未使用过线程,请先尝试使用它们。这在任何其他语言中都很有用,并且您会在网络上找到许多资源。 然后,如果您意识到需要更多并行性,则仍然可以切换回进程。
我总是喜欢使用多线程来简化问题,但亲和力确实存在一个真正的问题。据我所知,没有办法告诉Python的线程实现绑定到特定的处理器上。这可能对您来说不是问题,听起来似乎也不应该是问题。除非您有充分的理由不这样做,否则使用Python的线程实现可以轻松解决您的问题。
如果您决定使用进程,则可以通过几种方式在子进程之间共享信息:tcp/udp连接、共享内存或管道。这确实增加了一些开销和复杂性。
听起来你需要线程。
按照你描述的方式,似乎有一件事情实际上需要很多CPU...即模拟的实际运行。你想要的是更具响应性的显示,允许用户交互和图形更新,同时模拟正在运行。这正是Python的线程所构建的。但这不会让你能够利用系统上的多个核心/处理器。我不知道你的模拟看起来像什么,但如果它真的那么耗费CPU,那么它可能是分割的一个好候选对象。在这种情况下,您可以使用多进程在单独的核心/处理器上运行模拟的不同部分。然而,这并不是微不足道的...你现在需要某种方法来在进程之间传递数据,因为单独的进程不能轻松地访问相同的内存空间。