Python的线程和进程-python应用一般最多支持多少个线程

浏览: 2621

       今天在社区里面有朋友提问Python的应用一般最多支持多少个线程,原问题地址为:https://ask.hellobi.com/question/20157,个人觉得这个问题提的非常好,在这里总结整理一下,同时欢迎大家一起来讨论,相互学习。    

        在Python的学习过程中,一提到线程和进程,一般都会涉及到一个概念:“GIL”,在Python的原始解释器CPython中存在着GIL(Global Interpreter Lock,全局解释器锁),因此在解释执行python代码时,会产生互斥锁来限制线程对共享资源的访问,直到解释器遇到I/O操作或者操作次数达到一定数目时才会释放GIL。所以,虽然CPython的线程库直接封装了系统的原生线程,但CPython整体作为一个进程,同一时间只会有一个获得GIL的线程在跑,其他线程则处于等待状态。这就造成了即使在多核CPU中,多线程也只是做着分时切换而已。

       简单地说就是作为可能是仅有的支持多线程的解释型语言,Python的多线程是有compromise的,在任意时间只有一个Python解释器在解释Python bytecode。 

       如果我们的代码是CPU密集型,那么在GIL的作用下,多个线程的代码很有可能是线性执行的。所以这种情况下多线程是鸡肋,效率可能还不如单线程因为有context switch

       如果我们的代码是IO密集型,在这种情况下,多线程可以明显提高效率。比如爬虫,绝大多数时间爬虫是在等待socket返回数据。这个时候C代码里是有release GIL的,最终结果是某个线程等待IO的时候其他线程可以继续执行。

        通过上面我们可以知道:原则上我们就不应该用Python写CPU密集型的代码,因为效率确实会比较低,但如果确实需要在CPU密集型的代码里用concurrent,就去用multiprocessing库。这个库是基于multi process实现了类multi thread的API接口,并且用pickle部分地实现了变量共享。

        也会你可能会问,我怎么知道我的代码到底算CPU密集型还是IO密集型,教你个方法:

        multiprocessing这个module有一个dummy的sub module,它是基于multithread实现了multiprocessing的API。

        假设你使用的是multiprocessing的Pool,是使用多进程实现了concurrency

from multiprocessing import Pool

        如果把这个代码改成下面这样,就变成多线程实现concurrency

from multiprocessing.dummy import Pool

       两种方式都跑一下,哪个速度快用哪个就行了。


       另外推荐一些其他的多线程,多进程的处理机制,有兴趣的同学可以自行去学习。

           concurrent.futures:包含ThreadPoolExecutor和ProcessPoolExecutor,可能比multiprocessing更简单

           gevent:Python2.x的协程机制

           asyncio:Python3.x的标准异步IO处理包

推荐 4
本文由 牟瑞 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册