Python 2.6 亮点:multiprocessing模块

原本觉得Python 2.6只是Python 3.0的过渡版本,不会有太多的新功能。但看到这个2.6的重大改动列表,才发现本身挺落后的。在2.6中新增的multiprocessing模块也绝对是Python 2.6的杀手级应用(PEP371文档)。html

Multiprocessing简单的说就是模仿threading模块,让在Python中使用进程和使用线程同样方便。这个模块并非一个新的东西,原来是pyprocessing,只是在2.6里面被引入。但称为一个标准模块以后,地位就不同了,相似于ctype、sqlite被引入标准模块,就等于认可这些模块提供的功能具备普遍的需求。而multiprocessing之因此能跻身标准模块的行列,仍是由于GIL。GIL让python的解析器更容易写,但也让Python中的线程有点鸡肋的感受。事实上能受益于Python的线程模式的只有处于IO瓶颈的程序或者以图形为主程序。而对于渴求CPU的程序,线程不但不能让程序更快,反而让程序更慢。这能够说是Python的问题,也能够说是线程自己的问题。线程最大的罪恶无非是破坏了进程的隔离度,给程序员带来了便捷也带来了灾难,这方面有点像C。而面对线程的缺点,Python解释器想保护本身只有两条路:一是使用相似于GIL的技术,二是使用更复杂的细粒度同步技术。对于一个并不是面向于企业级市场(至少不是主要目的)的脚本语言,采用前者更符合现实要求:大部分Python程序都是单进程单线程的,大部分C库都不是线程安全的,而一个细粒度锁的解析器须要很是大的精力才能达到差很少的单线程性能,一般还带有一些隐藏得很深的bug。(若是再广义一点,其实还有第三条路,就是采用微进程+多线程解析器的技术,相似于Erlang所采用的。但这个技术主要问题在于扩展比较难写,难以跟已经存在的大量库和应用接口)但随着Python近年来的进一步流行,人们对Python的要求也愈来愈高,而GIL也显得有些阻碍你们发挥;而多核CPU的出现,更让Python有点难堪。此次multiprocessing进入标准模块,也算是对这个疑问的回答。python

Multiprocessing到底带来了什么?简单的说,是回到了多线程以前的老路上,多进程模式。多进程模式不是一个比多线程低级的模式。它的高隔离度带来了不少便利:安全,编码简单,能够透明的在集群上运行。并且,通过多年的发展,进程并不比线程耗费更多资源;在Linux上,进程和线程不管在建立速度和调度上,都已经没有明显差距。刚刚发布的google chrome浏览器就采用了多进程的模式。但对于以前的Python来讲,阻碍用户使用多进程模式的问题有障碍有两个:1,平台兼容问题;2,没有足够强大的IPC支持。平台兼容问题出在Windows上。Windows上没有相似fork的系统调用,也不能彻底模拟fork调用,让使用多进程模型编程多少有些担忧。IPC的问题更严重。操做系统通常提供不少IPC模式,从简单的Pipe到复杂的shm和socket。虽然Python也提供这些IPC方法,但这些IPC都是基于字节流或字节块的,而Python的基本单位是对象;这个差别让多进程代码中难免出现一些处理底层数据交流的代码,容易出错,也复杂。Miltiprocessing主要解决的就是这两个问题,尽可能磨平平台间的差别(固然,不能彻底磨平,详见multiprocessing的文档),也提供了更高层的API让使用者能忽略掉底层的IPC问题。在提供的IPC API上主要分两个部分。第一部分是对操做系统提供的IPC方法简单包装。好比,让pipe能够传送对象,让queue变得进程共享,甚至能够经过共享内存共享简单的对象。第二部分是对复杂对象提供共享支持:实现了一个简单的RPC模型,并复杂的对象能够在本地/远程主机间共享。第二部分提及来有点神奇,实际上挺简单的。Multiprocessing模块会fork一个进程,而这个进程会监听到某个端口;须要共享对象的进程(实际上应该说是线程,每一个线程都会有一个链接,固然,是你须要的时候才会链接过去)链接到这个处理进程,经过pickle编码发送请求,调用相应的方法,返回相应的结果;全部共享的对象都是存活在处理进程中。比较有意思的是,这个处理进程自己是使用线程来达到并发处理的目的……每一个链接都会单独由一个线程来处理。处理进程怎么解决同步问题呢?很简单,他不一样步,把同步的事情交给程序员去作。ios

固然,multiprocessing并非完美的。就目前来讲,pickle编码方式会是一个问题,程序员须要注意到什么资源能够传输,什么资源不能传输。单独进程处理复杂共享对象也会是一个问题,共享大量对象的时候会形成瓶颈;而简单的多线程并发模式也多是一个瓶颈,要知道Python的线程并非那么好。并且,试图掩盖网络的真实环境让本地和远程进程共享对象也是颇难解决的问题,目前,处理进程忽然崩溃,会致使全部数据丢失,也会致使其余进程不断从新链接形成假死。程序员

相关文章
相关标签/搜索