多进程还是多线程?
我正在用Python制作一个运行模拟的程序,界面是wxPython。在这个程序里,你可以创建一个模拟,程序会为你计算出结果。有时候,这个计算过程会非常耗时。
当用户开始一个模拟并设置初始状态时,我希望程序能够在后台持续进行计算,同时用户可以在程序里做其他事情。就像YouTube那种进度条,模拟只能播放到已经计算好的部分。
我应该使用多个进程还是多个线程呢?有人告诉我可以用multiprocessing
这个包,我看了一下,感觉不错,但我也听说进程和线程不同,进程之间不能共享很多信息(我觉得我的程序需要共享很多信息)。另外,我还听说过Stackless Python:这算是另外一个选择吗?我完全不清楚。
请给我一些建议。
9 个回答
- 无栈: 只用一个CPU。“任务单元”必须自愿让出控制权。抢占的选项并不是总能工作。
- 线程: 只用一个CPU。原生线程在运行20到100个Python操作后,会随机分配时间。
- 多进程: 使用多个CPU。
更新
深入分析
如果想要简单点,可以使用线程。不过,如果你调用的C语言函数需要很长时间才会返回,而这个函数又不释放锁,那就不太适合用线程了。
如果你的程序非常受限于CPU性能,并且你需要快速响应,那就用多进程。
不要使用无栈,因为我之前遇到过崩溃的情况。而且线程的效果基本上是一样的,除非你使用了几百个线程或者更多。
今年的Pycon大会上有一场关于多进程的精彩演讲。演讲的主要信息是:“除非你确定有问题需要用多进程解决,而这个问题用线程无法解决,否则就用线程。”
进程的开销比较大,而且要在进程之间共享的数据必须是可以序列化的(也就是可以用pickle处理的)。
你可以在这里查看演示文稿和视频: http://blip.tv/pycon-us-videos-2009-2010-2011/introduction-to-multiprocessing-in-python-1957019
“我查看了一下,感觉不错,但我也听说进程和线程不同,不能共享很多信息……”
这只是部分正确。
线程是进程的一部分——线程之间可以很容易地共享内存。这既是个好处,也可能是个问题——如果两个线程不太在意对方,它们可能会覆盖彼此的内存,导致严重的问题。
不过,进程之间也有很多方式可以共享信息。比如,使用Posix管道(a | b
)意味着进程a和进程b可以共享信息——a写入信息,b读取信息。这种方式在很多情况下都很有效。
操作系统会尽快把你的进程分配到每一个可用的核心上。这在很多情况下也很有效。
无栈Python和这个讨论没有关系——它更快,并且线程调度方式不同。但我觉得线程并不是解决这个问题的最佳选择。
“我觉得我的程序需要共享很多信息。”
你应该先解决这个问题。然后,确定如何围绕信息流来构建进程。使用“管道”非常简单自然;任何命令行工具都能轻松创建管道。
“服务器”是另一种架构,多个客户端进程可以从中央服务器获取信息或向其发送信息。这是共享信息的一个好方法。你可以使用WSGI参考实现来构建一个简单、可靠的服务器。