python多线程机制

python多线程机制

ID:9767988

大小:205.50 KB

页数:49页

时间:2018-05-08

python多线程机制_第1页
python多线程机制_第2页
python多线程机制_第3页
python多线程机制_第4页
python多线程机制_第5页
资源描述:

《python多线程机制》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库

1、Python多线程机制开发多线程的应用系统,是在日常的软件开发中经常会遇到的需求。现在的编程语言都为多线程开发提供了很好的支持,无论是通过库的支持还是将多线程机制内建在语言之中。Python也为多线程系统的开发提供了很好的支持。同样身为动态语言,Ruby也提供了多线程的支持,但是在Ruby1.9之前的多线程机制是在语言的实现中模拟了线程及线程调度机制,而并没有使用操作系统本身的线程机制(在以后的描述中,我们称为原生线程)。Ruby1.9中整合了YARV作为Ruby新的虚拟机,在YARV中,将操作系统的原生线程引入了Ruby。每一个Ruby线程都对是操作系统上的一个线程,在Ruby内部,

2、维护着一个全局资源锁,一个Ruby线程必须首先获得这个锁,才能成为活动的线程,从而使用Ruby虚拟机的全局资源。这一切,在Python中早已实现,Python中的线程从一开始就是操作系统的原生线程,而Python虚拟机也同样使用一个全局解释器锁(GlobalInterpreterLock,GIL)来互斥线程对Python虚拟机的使用。15.1 GIL与线程调度为了理解Python为什么需要GlobalInterpreterLock(GIL),考虑这样的情形:假设有两个线程A、B,在两个线程中,都同时保存着对内存中同一对象obj的引用,也就是说,这时obj->ob_refcnt的值为2。

3、如果A销毁对obj的引用,显然,A将通过Py_DECREF调整obj的引用计数值。我们知道,Py_DECREF的整个动作可以分为两个部分:Ø        --obj->ob_refcnt;Ø        if(obj->ob_refcnt==0)destoryobjectandfreememory。如果A在执行完第一个动作之后,obj->ob_refcnt的值变为1。不幸的是,恰恰在这个时候,线程调度机制将A挂起,而唤醒了B。更为不幸的是,B同样也开始销毁对obj的引用。B完成第一个动作之后,obj->ob_refcnt为0,B是一个幸运儿,它没有被线程调度打断,而是顺利地完成了接

4、下来的第二个动作,将对象销毁,内存释放。好了,现在A又被重新唤醒,可惜现在已经物是人非,obj->ob_refcnt已经被B减少到0,而不是当初的1。按照约定,傻乎乎的A开始再一次地对已经销毁的对象进行对象销毁和内存释放的动作。这样的结局是什么?只有天知道。为了支持多线程机制,一个基本的要求就是需要实现不同线程对共享资源访问的互斥,Python也不例外,这正是引入GIL的根源所在。Python中的GIL是一个非常霸道的互斥实现,正如它的名字所暗示的,GIL是一个解释器(Interpreter)——为了呼应GIL中的Interpreter,本章中,我们会以解释器来称呼虚拟机——级的互斥机

5、制,也就是说,在一个线程拥有了解释器的访问权之后,其他的所有线程都必须等待它释放解释器的访问权,即使这些线程的下一条指令并不会互相影响。初看上去,这样的保护机制粒度太大了,我们似乎只需要将可能被多个线程共享的资源保护起来即可,对于不会被多个线程共享的资源,完全可以不用保护。实际上,在Python的发展历史中,确实出现过这样的解决方案,但是令人惊奇的,这样的方案在单处理器上的多线程实现的效率上却没有GIL的方案好。所以现在Python中的多线程机制是在GIL的基础上实现的。当然,这样的方案也意味着,无论如何,在同一时间,只能有一个线程能访问Python所提供的API。注意这里的同一时间对

6、于单处理器是毫无意义的,因为单处理器的本质是不可能并行的,但是对于多处理器,情形就完全不同了,同一时间,确实可以有多个线程独立运行,然而Python的GIL限制了这样的情形,使得多处理器最终退化为单处理器,性能大打折扣。这一点其实早已被Python社区所认识,也进行了大量的探索。大约在99年的时候,GregStein和MarkHammond两位老兄基于Python1.5创建了一份去除GIL的branch,但是很不幸,这个分支在很多基准测试上,尤其是单线程操作的测试上,效率只有使用GIL的Python的一半左右。因为细粒度的锁机制会导致大量的加锁、解锁的操作,而加锁、解锁对于操作系统来说

7、,是一个比较重量级的动作;另一方面,没有了GIL的保护,编写Python扩展模块的难度大大增加。所以,到目前Python的最新版本2.5为止,GIL仍然是多线程机制的基石,而我们也仍然将视线集中在单处理器上。实际上,在去年5月份Python3000的邮件列表上,Python的创造者,Guido,提出了一个比较可行的的解决方案,在多处理器的情况下,完全可以创建多个Python进程,充分使用多处理器,进程之间通过IPC的方式进行通信。当然,Guid

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。