“唉,还没毕业就受到甲方的支配,等以后进了公司可咋整啊。”小白嘴里这么吐槽,但心理上还是不敢怠慢,只能恋恋不舍地关掉眼前的游戏,打开了 Python 代码思考了起来。

“现在的程序是单线程的,那就用多线程模型来优化吧,嘿嘿,我太机智了!”小白打心底感谢前段时间里学习到的线程的知识。“Python 里好像是 threading 模块负责多线程的,就决定是你了,threading !”

花了两三个小时,小白终于把程序改好了,他长舒一口气,点击 Run ,开始测试运行时间。

“woc!怎么运行时间还变长了?”看着屏幕上显示的测试结果,小白傻眼了,这多线程怎么不顶用?自己明明是按官方文档来的啊!

debug 无果,小白只好寻求好朋友小明的帮助。

“哈哈哈,你居然用 python 的多线程?你不知道 python 的多线程被很多人称作「鸡肋」吗?”

“啊,不会吧?还有这种说法?我要是知道我肯定就不用多线程来改了。。。可为什么 python 的多线程就鸡肋了?那多线程爬虫是怎么回事?”

“我先给你解释下 python 下的多线程是怎么一回事吧。Python 是一门解释型语言,它的执行是由解释器来控制的,我们一般都会使用默认的 Cpython 解释器,这些我想你应该清楚。”

“那当然,这在一开始学 Python 的时候老师就讲过了。”

“那你知不知道什么是 GIL?”小明问道。

小白挠挠头,尴尬的回答:“我没听说过。”

“也是,你要是知道 GIL ,就能弄明白 Python 的多线程了。GIL,全称是 Global Interpreter Lock ,全局解释锁 ,专门给解释器用的。”

“蛤?解释器还要需要锁? ”

“这个锁别有妙用,让我先考考你,C 语言能不能在用户态下做到线程级别的时间片轮转?”

“不能!操作系统里讲过了,我还记得上次你教我的内容~”小白得意的回答。

关于线程,详细的在这里:

“但是 python 能做到!python 里,解释器可以记录每一个线程执行了多长时间——时间一到,就能够切换到另一条线程。”

“有点意思,听起来像是解释器充当了操作系统的角色,然后为 python 线程提供了时间片轮转的能力。”

tobe 注:理论上 C 语言也可以做到,毕竟 python 解释器就是用 C 语言写的。

“解释的很到位,我再说回 GIL 吧,在多核还没有出现的时候,就已经有线程的存在了,GIL 就是拿来给线程加锁的,当一个线程将要执行时,解释器会把 GIL 锁给这个线程,其他线程因为没有锁,是无法运行的。等到持有锁线程阻塞或者运行 100 个字节码,解释器就会把锁交给其他线程。”

“但是这个 GIL 锁是全局(Global)的,也就导致即使是多核情况下,一次也只有一个线程能运行,从整体上看,整个程序是串行的。”

小白恍然大悟:“怪不得我的程序还变慢了,原来 python 的多线程不仅不能利用多核,还因为线程切换拖慢了我程序的执行速度!我想很多人应该都遇到过我这个问题吧,Python 社区为什么不修改这一特性,让多线程也做到并行呢?”

小明叹了口气:“哪有这么简单,修改锁的设计是很难的,我听说 MYSQL 拆分 buffer pool mutex 这个全局锁花了好多年呢。不过 Python 社区为此还是做了不少挽救工作的,比如在线程睡觉(sleep),等待连接的时候主动释放 GIL,让其他线程继续执行。拿爬虫程序来说吧,单个爬虫总会花时间在下载网页上,很多 CPU 时间就浪费掉了, 提供 sleep 机制后,这些爬虫可以在等待下载时释放 GIL 锁,把机会让给其他爬虫,这样整体运行速度能够得到大幅提升。”

“我好像明白了,”小白感觉自己被打通了任督二脉:“也就是说 Python 的多线程适合 I/O 密集型的程序,但是对计算密集型程序就不那么友好了~ 诶等等,那我怎么办?我还打算用多线程优化我的程序呢!”

“让 python 利用多核的方法还是有的,比如说,让 python 调用 C 语言的代码,在 C 语言里实现多线程,因为 C 语言里没有 GIL 锁,这些线程不会受到 GIL 的约束,也就能并行了。”

小白一个劲儿摇头:“不不不不不,好不容易写完的 Python 代码,你让我改成 C?这不是要我的命吗!我拒绝!”

“这不是还有第二种方法嘛——使用多进程,Python 里有个 multiprocessing 模块,可以创建多个进程,因为不同的进程使用不同的解释器,所以它们有各自的 GIL,互不干扰,自然就能完成并发了。

“这个方法听起来才正常嘛,我马上就回去试试,谢谢你了!”


希望你在看完我的文章之后有所收获~(求点赞呐!)

Python 的多线程是鸡肋?的更多相关文章

  1. Python多进程和多线程是鸡肋嘛?【转】

    GIL是什么 Python的代码执行由 Python虚拟机(也叫解释器主循环,CPython版本)来控制,Python在设计之初就考虑到在解释器的主循环中,同时只有一个线程在运行.即每个CPU在任意时 ...

  2. Python的多线程和多进程

    (1)多线程的产生并不是因为发明了多核CPU甚至现在有多个CPU+多核的硬件,也不是因为多线程CPU运行效率比单线程高.单从CPU的运行效率上考虑,单任务进程及单线程效率是最高的,因为CPU没有任何进 ...

  3. python 的多线程执行速度

    python 的多线程有点鸡肋,适用场景有局限,单位时间多个核只能跑一个线程. 有泳池一个,四个泵,但只有一个人,一人只能开启管理着其中一个,所以四个泵没什么用.但是,如果泵的工作时间与冷却恢复时间是 ...

  4. Python中多线程与多进程的恩恩怨怨

    概念: 并发:当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配给各个线程执行,在一个时间段的线程代码运 ...

  5. [ Python - 11 ] 多线程及GIL全局锁

    1. GIL是什么? 首先需要明确的一点是GIL并不是python的特性, 它是在实现python解析器(Cpython)时所引入的一个概念. 而Cpython是大部分环境下默认的python执行环境 ...

  6. Python的多线程(threading)与多进程(multiprocessing )

    进程:程序的一次执行(程序载入内存,系统分配资源运行).每个进程有自己的内存空间,数据栈等,进程之间可以进行通讯,但是不能共享信息. 线程:所有的线程运行在同一个进程中,共享相同的运行环境.每个独立的 ...

  7. Python GIL 多线程机制 (C source code)

    最近阅读<Python源码剖析>对进程线程的封装解释: GIL,Global Interpreter Lock,对于python的多线程机制非常重要,其如何实现的?代码中实现如下: 指向一 ...

  8. Python实现多线程HTTP下载器

    本文将介绍使用Python编写多线程HTTP下载器,并生成.exe可执行文件. 环境:windows/Linux + Python2.7.x 单线程 在介绍多线程之前首先介绍单线程.编写单线程的思路为 ...

  9. Python实现多线程调用GDAL执行正射校正

    python实现多线程参考http://www.runoob.com/python/python-multithreading.html #!/usr/bin/env python # coding: ...

随机推荐

  1. MySQL之增删改查之

    MySQL之增删改查   前言:以下是MySQL最基本的增删改查语句,很多IT工作者都必须要会的命令,也是IT行业面试最常考的知识点,由于是入门级基础命令,所有所有操作都建立在单表上,未涉及多表操作. ...

  2. 编程范式 --- 函数式编程(Funtional Programming,简称FP)

    函数式编程(Funtional Programming,简称FP)是一种编程范式,也就是如何编写程序的方法论 主要思想:把计算过程尽量分解成一系列可复用函数的调用 主要特征:函数是"第一等公 ...

  3. elasticsearch应用于产品列表

    package com.linkwee.web.service; import java.util.List; import com.linkwee.api.request.cim.ProductPa ...

  4. Linux mint 启动文本模式(不启动图形界面)

    Linux Mint 系统用了很久,很顺手,赞一个! 有一天想同时运行多个虚拟机linux系统做实验,想着只启动文本模式可以省点内存资源,结果试了多种方法都不成功,网上现有针对Ubuntu原版和Cen ...

  5. Java8新特性——stream流

    一.基本API初探 package java8.stream; import java.util.Arrays; import java.util.IntSummaryStatistics; impo ...

  6. MongoDB的可视化工具(Studio 3T)

    ​​ 前面我们已经介绍了MongoDB怎么安装,接下来要安装他的可视化工具——Studio 3T. 先到这下载一个压缩包,百度网盘,https://pan.baidu.com/s/1M8mlWo334 ...

  7. Ocelot自定义管道中间件

    Ocelot是啥就不介绍了哈,网关大家都知道,如果大家看过源码会发现其核心就是由一个个的管道中间件组成的,当然这也是Net Core的亮点之一.一个请求到来,会按照中间件的注册顺序进行处理,今天的问题 ...

  8. 主动降噪技术(ANC)的前生今世–行业分析

    一 原始玩家 1978年,创始人Amar G. Bose博士在从欧洲飞往波士顿的飞机上,发现飞机引擎的噪音扫净了他戴耳机欣赏音乐的兴致.这激发了他在BOSE公司进行一项消噪科技的研究.弹指之间,十年过 ...

  9. 爬虫那点事,干就玩了之seleunim

    目录 selenium 环境准备 代码环境 开始爬虫 操作js 截图 切换窗口 在当前窗口切换访问地址 管理cookie # 加入战队 微信公众号 # 加入战队 微信公众号 做技术我们最重要的是[做] ...

  10. 刷新:重新发现.NET与未来

    微软在比尔·盖茨手中创立并崛起, 成为PC互联网时代的霸主,很多70,80后都有MVP Ediwang的体验: 当时的微软对我来说就是神的存在.因为我认识电脑到使用电脑的一切几乎都离不开这家伟大的公司 ...