python multiprocessing模块_Python 2.6 亮点:multiprocessing模块

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

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进入标准模块,也算是对这个疑问的回答。

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编码发送请求,调用相应的方法,返回相应的结果;所有共享的对象都是存活在处理进程中。比较有意思的是,这个处理进程本身是使用线程来达到并发处理的目的……每个连接都会单独由一个线程来处理。处理进程怎么解决同步问题呢?很简单,他不同步,把同步的事情交给程序员去做。

当然,multiprocessing并不是完美的。就目前来说,pickle编码方式会是一个问题,程序员需要注意到什么资源可以传输,什么资源不能传输。单独进程处理复杂共享对象也会是一个问题,共享大量对象的时候会造成瓶颈;而简单的多线程并发模式也可能是一个瓶颈,要知道Python的线程并不是那么好。而且,试图掩盖网络的真实环境让本地和远程进程共享对象也是颇难解决的问题,目前,处理进程突然崩溃,会导致所有数据丢失,也会导致其他进程不断重新连接造成假死。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值