我应该使用进程还是线程?
在我的脚本中,有一个函数foo,它主要是用pynotify来定时通知用户一些事情,比如每隔15分钟提醒一次。
def foo:
while True:
"""Does something"""
time.sleep(900)
我的主脚本需要和用户互动,还要做其他事情,所以我不能直接调用foo()函数。
那么,有什么更好的方法来实现这个以及为什么呢?是使用分叉(fork)还是线程(threads)?
5 个回答
使用多个进程可以让你同时利用多个CPU核心,而在CPython中,使用线程则不能做到这一点(线程是轮流使用一个CPU核心的)。所以,如果你有需要大量计算的工作,并且一定想用线程的话,可以考虑Jython或IronPython;在CPython中,这个考虑通常会让人更倾向于使用multiprocessing
模块,而不是threading
模块(这两个模块的接口很相似,因为multiprocessing
是为了方便替代threading
而设计的)。
除了这个重要的考虑,在线程的选择上,在Windows系统上,线程可能更合适(因为在Windows上创建新进程比较耗资源),但在Unix类系统(比如Linux、BSD版本、OpenSolaris、MacOSX等)上,情况就不一样了,因为在这些系统上创建新进程更快。不过,如果你使用IronPython或Jython,最好还是检查一下你关心的平台上,这种情况在相关的虚拟机中是否仍然适用——IronPython使用的是CLR,可以是.NET或Mono,而Jython则是你选择的JVM。
对于这类问题,使用线程或分叉进程似乎都不是最佳选择。如果你只是想每15分钟通知用户一次某件事,那为什么不使用像GLib或Twisted的事件循环呢?这样可以让你安排一些需要偶尔运行的操作,同时继续进行程序的其他部分。
我不会告诉你该用哪个,但我可以给你讲讲它们各自的一些优点:
线程启动速度比进程快,而且线程使用的系统资源比进程少,比如内存、文件句柄等。线程还可以通过共享变量来进行通信(不过很多人觉得这其实是个缺点,下面会提到)。
进程各自有独立的内存和变量,这意味着进程之间一般是通过发送消息来沟通。这样做比让线程通过共享内存来沟通要简单得多,而且更容易做到正确。 进程还可以真正并行运行,如果你的电脑有多个CPU核心,就可以让它们都忙碌起来。对于Python*来说,全局解释器锁限制了线程在多个核心上的使用。
* - 这里指的是CPython,也就是你去http://python.org下载的Python版本。其他一些Python实现(比如Jython)不一定会限制Python线程在多个CPU上同时运行。感谢@EOL的澄清。