当前位置: 首页 > 后端技术 > Python

Python的多线程是鸡肋吗?

时间:2023-03-26 12:59:44 Python

1。“哎,我还没毕业就被甲方支配了,进公司能干什么?”小白抱怨了那么多,但心理上还是不敢怠慢,只能无奈的关闭了眼前的游戏,打开Python代码想了想。“现在的程序是单线程的,那就用多线程的模型优化一下吧,嘿嘿,我真聪明!”小白从心里感谢他前段时间学到的线程知识。“在Python中,threading模块好像是负责多线程的,就看你的了,threading!”花了两三个小时,小白终于把节目换了。他松了口气,点击运行,开始测试运行时间。“哇哦!为什么运行时间越来越长了?”看着屏幕上显示的测试结果,小白傻眼了。为什么这个多线程不起作用?我明明是按照官方文档来的!调试失败,小白只好求助于好朋友小明。2.“哈哈哈,你居然用python的多线程?你不知道python的多线程被很多人称为“鸡肋”吗?”“哦不是吗?还有这种说法?要是我知道,肯定不用了用多线程换吧。。。但是为什么python的多线程这么鸡肋?多线程的爬虫怎么了?》我给大家解释一下python下的多线程到底是个什么东西。Python是一种解释型语言,它的执行是由解释器控制的,我们一般使用默认的Cpython解释器,这个我想你应该知道。”当然,这是我初学Python时老师说的。”“那你知道GIL是什么吗?”小明问。小白挠了挠头,尴尬的回答:“没听说过。multithreading.GIL,全称GlobalInterpreterLock,全局解释器锁,解释器专用。”“蛤?解释器还需要锁吗?”“这个锁有妙用,我先测试一下,C能吗语言在用户态实现线程级时间片轮转?”“不能!我在操作系统里提过,我还记得你上次教我的~”小白得意的回答道。关于线程,这里有详细介绍:“但是python可以做到!在python中,解释器可以记录每个线程执行了多长时间——一旦时间到了,它就可以切换到另一个线程。”“有点意思,听起来像是解释器充当操作系统,然后为python线程提供轮换时间片的能力。"tobe注:理论上C语言也可以做到,毕竟python解释器是用C语言写的。"解释非常好。再说说GIL。多核还没有出现的时候,线程就已经有了。是的,GIL就是用来锁线程的。当一个线程即将执行时,解释器会将GIL锁定到这个线程上。其他线程无法运行,因为没有锁。当持有锁的线程阻塞或运行100个字节码时,解释器会将锁交给其他线程。”“但是这个GIL锁是全局的(Global),也就是说即使在多核的情况下,一次也只能运行一个线程。总的来说,整个程序是串行的。”小白恍然大悟:“怪不得我的程序还慢呢。原来python的多线程不仅不能发挥多核的优势,还会因为线程切换拖慢我程序的执行速度!我想应该很多人都遇到过我的问题。为什么Python社区不修改这个特性,让多线程也可以并行化?3.小明感叹:“哪有那么简单,修改锁的设计是很难的,听说MYSQL用了很多年才拆分bufferpoolmutex的全局锁。不过Python社区有为此做了很多挽救工作,比如在线程休眠等待连接时主动释放GIL,让其他线程继续执行。以爬虫程序为例,单个爬虫总是会花时间下载网页,会浪费大量的CPU时间,在提供休眠机制后,这些爬虫可以在等待下载的时候释放GIL锁,把机会让给其他爬虫,整体运行速度可以大大提高。“我好像明白了,”小白感觉自己已经接通了任渡的第二个频道:“也就是说,Python的多线程适合I/O密集型程序,但对计算密集型程序就不那么友好了程序~嘿等等,我该怎么办哦?我还打算用多线程优化我的程序!”“还有办法让python使用多核。比如让python调用C语言的代码,用C语言实现多线程。因为C语言中没有GIL锁,所以这些线程不会受到GIL的约束,也就是可以并行运行。”小白不停摇头:“不不不不,好不容易写出来的Python代码,你让我改成C?这不是要我的命吗!我拒绝!”“难道没有第二种方式——使用多进程,Python中有一个多进程模块,可以创建多个进程,因为不同的进程使用不同的解释器,所以它们有自己的GIL,互不干扰,自然就可以完成并发了。”“这个方法听起来很正常,我马上回去试试,谢谢!》希望大家看完我的文章有所收获~(请点赞!)