首页 > 编程知识 正文

骆昊python100天(python中多线程是真的还是假的_天啦噜!Python多线程居然是骗人的?)

时间:2023-05-04 07:28:50 阅读:122094 作者:230

Python说明执行原理

我是Python线程,工作是解释程序员写的Python代码。

所谓解释执行,是因为Python是高级语言,CPU的那个家伙不知道Python代码,需要执行的时候动态地翻译成CPU指令。

我“编译”了Python源代码后,变成了一个个字节码文件。 pyc,这是二进制文件。 人类不知道。 只有我知道。

之后,我的工作变得简单了,在所有命令都执行之前,可以继续提取字节码文件中的“命令”来说明执行,然后休息。

GIL

随后,多线程编程技术流行起来,进程中不仅有我,还有几个新伙伴。

我们本以为可以和平共处,但这样就麻烦了。 我们做了各自的工作,经常把内存空间当成问题,也没找到推背的人。

有一天,我受不了了,召集大家讨论解决方案。

“伙伴们,我们不能再这样分开做了。 我们是一个团队。 要互相合作,一个线程可以走得很快,但只有一个线程在一起才能走得很远。 ”

另一个帖子说:“老板,如果你有什么想法,请坦率地说。”

“不然,就锁上吧! 很简单,每个线程要执行代码,就必须申请这个锁。 不申请就不能执行。 否则,我们必须等待,”我说。

“那个什么时候释放? ”

“不做计数器,每个线程数到100就释放,保证别人有机地执行吗? ”

“怎么计数? 是否要在每次执行1字节码时进行计数? ”

“可以,但不用那么死板。 有些命令很简单。 马上就能做好。 不算也可以”

“可以,但是还不到100个,就屏蔽了I/O操作,占领了锁,那不是浪费资源吗? ”

伙伴们在七嘴八舌地讨论着。

“那就这样,把两种情况结合起来,通常数到100就解锁一次,但是遇到堵车的时候,也要提前解锁。 怎么样? ”我想说。

大家都点头同意,然后我们把这个锁命名为全球解释器锁GIL。

自从用了GIL,我们大男人工作变得有规律,不再破坏公共资源。

升级版GIL

此后,多核技术开始兴起,可以在一个CPU中同时运行多个线程。 伙伴们高兴地传播了这个消息。

“老板,现在CPU有多核。 我可以一起运行,你能帮我去掉那个GIL吗? 这样可以利用多核的好处。 ”

“是啊,旁边的Java线程总是嘲笑我们看起来人很多,但实际上只运行了一个线程。”

虽然不是件容易做的事,但多年来我们都是这样工作的。 突然去除,就算有问题也没有人敢承担责任啊。

新线程抱怨说:“但是老板,现在这个GIL锁不公平。”

“哪里不公平? ”

“当我试图运行代码时,我发现你的手被锁上了,我只能当场等待。 等了半天也睡着了。 我终于等到你被释放了。 操作系统唤醒了我,想申请钥匙,但又被你抢了。 完全是浪费。”新的帖子露出了不满的表情。

“是的,老板,我也发现了。 这不是偶发现象。 我观察了很久。 经常发生。 另一个线程伙伴也说:“大家都很不满,发现明明经常清醒,却徒劳地忙碌着,徒劳地浪费CPU资源。”

对不起,“嗯,这确实是个问题”

“还没结束,”新线程继续说。 “现在按字节码的指令数进行计数。 但是,有些指令代码简单、复杂,同样可以数到100。 一些线程可以长时间运行,一些线程很快退出。 不公平”

伙伴们提出的所有问题都很重要,看来是时候升级GIL了。

经过激烈的讨论,我们改善了原来的GIL,采用了新的战略。 不是计数方式,而是变更为时间片方式。 每个线程的执行时间片为5000微秒。

为了避免释放GIL后立即又被自己夺走,添加了新的锁定实现了强制线程切换

改善后,这样终于公平了。 各位伙伴已经什么都不说了。 我还能安心工作。

结语

Python是一种描述运行的语言,具有强大的第三方库和跨平台能力。 近年来,Python闪耀着第二个春天的光芒,席卷了爬虫类、网络开发、机器学习等多个领域。

但是,长期以来,Python最恶毒的是,他有一把叫GIL的钥匙。 Python无法真正实现多线程执行,无法利用多核CPU的高性能。

实际上,这个锁和Python没有丝毫关系,运行Python的解释器:负责解释CPython的锅。

CPython是用c语言编写的Python解释器,是应用最广泛的Python解释器,如果没有特殊说明,Python是指此CPython解释器。

Python诞生之初,多线程技术还没有像今天这样深入人心。 甚至多核CPU也是在Python诞生多年后出现的。 早期的解释器使用粗暴的GIL来控制多个线程,但它们既方便又简单,同时也成为了CPython的巨大历史包袱。

在Python3.2之前,Python使用简单的计数方法来统计控制每个线程的执行时间。 我在这里

之后,引入了更为公平的时间片方式来升级替换。

过去二十年,曾经有许许多多大牛都尝试彻底去除GIL,但都没有完美成功。

虽然Python没能彻底去除GIL,好在,提供了其他几种方式“曲线救国”实现并发:Ctypes 通过编写C语言扩展与Python交互,在C语言层面绕过GIL实现多核利用。

MultiProcess Python提供了MultiProcess,通过多进程的方式绕过GIL

协程 协程又称用户态线程,Python3.4版本后新增了对协程的支持,也是对性能的提升提供了一种选择。

这篇文章用第一人称大白话的方式讲述了GIL在CPython解释器中的工作原理,大家都理解了吗?

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。