学习python的进程和线程以来,对这两个概念一直都处于模糊状态,所以决定花点时间好好学习一下这块知识。以下是我自己在学习过程中形成的一些疑问以及搜集的一些相应的比较好的答案,整理如下,方便复习自查。

我们可能听过这样的说法:由于GIL的存在,在多个CPU情况下python的多线程是个鸡肋的存在。至于为什么会这样,下文转载的一篇博文中有比较详细的解说。

虽然python多线程鸡肋,但是在阅读python cookbook相关章节时,看到这么样的描述:“GIL带来的最明显的影响就是多线程的python程序无法充分利用多个CPU核心带来的优势(即,一个采用多线程技术的计算密集型应用只能在一个CPU上运行.....如果我们的程序主要是在做I/O操作,比如处理网络连接,那么选择多线程技术常常是一个明智选择。因为他们大部分时间都花在等待对方连接上了)”(来自python cookbook中文版第三版12.9小节,如何规避GIL带来的限制)。其实对于这句话的理解,同样在下面转发的博文中有解释,这里只是用一个更权威的描述来佐证博文中的论述。

所以说,多个CPU情况下,对于I/O密集型操作,使用多线程技术是有益无害的,但是,一旦某个线程是CPU密集型操作,那么该线程就可能长时间占用GIL,导致其他线程长期等待,也无法发挥多个CPU带来的优势,此时应该尽量使用多进程,而不是多线程。既然python多线程仍有用武之地,所以还是有必要好好学习一下这块知识。

I/O操作是否会一直占用CPU?

这个问题在刚开始学习python线程和五大I/O模型的时候困惑了我一段时间,因为我的认识中,所有程序都是由CPU由上到下一条一条执行的。但是在学习I/O模型时,比如下图的异步I/O模型,图左侧aio_read函数发出一个system call之后就return了,然后CPU接着搞事情,但是同时图右侧又注明wait for data,什么鬼,谁在等?难道CPU能分身不成?虽然猜测应该是有别的外设(好在曾经搞过嵌入式,知道外设这概念)在处理数据发送和接收,然后通过中断通知CPU处理结果,但是没有正经理论支撑还是放心不下,于是知乎了一下,果然还是得到了比较满意的答案,总的来说就是IO所需要的CPU资源非常少。大部分工作是分派给DMA(Direct Memory Access)直接内存存取完成的。我把知乎该条回答复制到了我的博客园,以便复习查看点击这里

明白了这个,也就明白了CPU密集型和I/O密集型在使用线程中的区别,CPU密集型代码段需要一直占用CPU,而I/O密集型代码,可以在进行I/O操作的时候让出CPU控制权,而I/O操作的过程是交给DMA处理的,并不需要CPU直接参与。

多核处理器,一个进程的多个线程能否在不同CPU中并行运行?

之前一直以为多核处理器每个CPU只能并行执行不同的进程,因为进程是资源分配的最小单位,如果一个进程的不同线程运行在不同CPU,那么线程间通讯应该比较困难,后来觉得如果这样的话,一个进程的多个线程只能在同一个CPU下轮流执行,对于任务不多的情况下,会导致其他CPU在那里空转,实在是浪费资源,百度了很久,都没有得到正面的回答,在StackOverflow上得到一个好一点的回答。

先把结论摆出来,那就是:同一进程的多个线程,是可以在不同CPU并行(不是并发)执行的。形象一点就是说,假设有一个进程的两个线程A和B,以及两个核CPU1和CPU2,操作系统可以把线程A分配给CPU1执行,同时线程B分配给CPU2执行,以达到并发执行的效果。

原文地址点击这里

上面两个回答来自同一个提问,简单概括一下第一个回答,意思就是一个包含多个线程的进程,操作系统会决定哪个线程在哪个CPU执行(通过机智的试探法来提升负载平衡和优化能耗等)。第二个回答大概意思是,”操作系统不太在意线程来自哪个进程,它通常把线程安排给不同核的处理器,不管线程来自哪个进程,这可以使得一个进程的四个线程在同一时刻运行“。

python的GIL全局锁是什么,为什么说它导致了python多线程的鸡肋,如何规避这种不利影响?

本来是打算自己查资料做实验总结的,后来发现这个话题已经有相当多优秀的博文可供参考,看着别人的文章,发现自己重新造轮子有点多此一举,而且不自信能写出人家的深度,不如直接拿来主义,哦不,是借鉴参考一下。果不其然,有时候做做伸手党,还是emmm......真香...。

好了,直接放上一篇看完很受益的博文的链接,方便以后复习时查看。

博文链接

关于该博文中说到的不执行任何I/O操作的CPU密集型线程,会一直占用GIL,导致其他I/O密集型线程进入无尽的等待,这个说法应该是值得商榷的,在看《python cookbook》12.9.2章节的时候,页脚有这么一段注释,我把它贴出来:

也就是说,当CPU密集型线程占用GIL后,python解释器在执行了一定数量的python代码后会主动释放GIL,以便让其他线程得到执行的机会,所以博文中所述的CPU密集型线程会一直占用GIL的说法是有疑点的,不过博文中是使用的python2,而cookbook是基于python3。

python多线程一些知识点梳理的更多相关文章

  1. day-3 python多线程编程知识点汇总

    python语言以容易入门,适合应用开发,编程简洁,第三方库多等等诸多优点,并吸引广大编程爱好者.但是也存在一个被熟知的性能瓶颈:python解释器引入GIL锁以后,多CPU场景下,也不再是并行方式运 ...

  2. python多线程相关知识点

    1. 信号量 信号机维护着一个计数器,指定可同时访问资源或者进入临界区的线程数.每次有一个线程获得信号机时,计数器-1.若计数器为0,其他线程就停止访问信号机 Semphore,是一种带计数的线程同步 ...

  3. Java多线程入门知识点梳理

    前言 在多核时代,高并发时代,对系统并行处理能力有很高要求.多线程就是这个时代最好的产物.通过使用多线程可以增强系统并行处理能力,提高CPU资源的有效利用:从而提高系统的处理能力.常见应用场景如:多窗 ...

  4. Python多线程Selenium跨浏览器测试

    前言 在web测试中,不可避免的一个测试就是浏览器兼容性测试,在没有自动化测试前,我们总是苦逼的在一台或多台机器上安装N种浏览器,然后手工在不同的浏览器上验证主业务流程和关键功能模块功能,以检测不同浏 ...

  5. 搞定python多线程和多进程

    1 概念梳理: 1.1 线程 1.1.1 什么是线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发 ...

  6. python多线程和多进程

    1 概念梳理: 1.1 线程 1.1.1 什么是线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发 ...

  7. [转]Python多线程与多线程中join()的用法

    https://www.cnblogs.com/cnkai/p/7504980.html Python多线程与多进程中join()方法的效果是相同的. 下面仅以多线程为例: 首先需要明确几个概念: 知 ...

  8. 【Python】详解Python多线程Selenium跨浏览器测试

    前言 在web测试中,不可避免的一个测试就是浏览器兼容性测试,在没有自动化测试前,我们总是苦逼的在一台或多台机器上安装N种浏览器,然后手工在不同的浏览器上验证主业务流程和关键功能模块功能,以检测不同浏 ...

  9. python 多线程示例

    原文链接:http://www.cnblogs.com/whatisfantasy/p/6440585.html 1 概念梳理: 1.1 线程 1.1.1 什么是线程 线程是操作系统能够进行运算调度的 ...

随机推荐

  1. 干货 | 10分钟搞懂branch and bound(分支定界)算法的代码实现附带java代码

    Outline 前言 Example-1 Example-2 运行说明 00 前言 前面一篇文章我们讲了branch and bound算法的相关概念.可能大家对精确算法实现的印象大概只有一个,调用求 ...

  2. 64、Spark Streaming:StreamingContext初始化与Receiver启动原理剖析与源码分析

    一.StreamingContext源码分析 ###入口 org.apache.spark.streaming/StreamingContext.scala /** * 在创建和完成StreamCon ...

  3. nodejs之mysql查询

    示例代码中的mysql版本 2.14.1 参考代码 /** * 测试mysql连接 */ var mysql = require('mysql'); var connection = mysql.cr ...

  4. 洛谷P2744 量取牛奶

    题目 DP或者迭代加深搜索,比较考验递归的搜索. 题目第一问可以用迭代加深搜索限制层数. 第二问需要满足字典序最小,所以我们可以在搜索的时候把比当前答案字典序大的情况剪枝掉. 然后考虑怎么搜索,对于每 ...

  5. 修改elementUI源码新增组件/修改组件

    前言 经常我们会遇到elementUI组件库期间有5%达不到我们想要的需求,第一我们重新写组件,第二我们改源码 安装element https://github.com/ElemeFE/element ...

  6. Beta冲刺(1/5)

    队名:無駄無駄 组长博客 作业博客 组员情况 张越洋 过去两天完成了哪些任务 初步任务分配 提交记录(全组共用) 接下来的计划 完善接口文档 还剩下哪些任务 学习软工的理论课 学习代码评估.测试 燃尽 ...

  7. 刷题记录:2018HCTF&admin

    目录 刷题记录:2018HCTF&admin 一.前言 二.正文 1.解题过程 2.解题方法 刷题记录:2018HCTF&admin 一.前言 经过一个暑假的学习,算是正经一条web狗 ...

  8. TCP选项之SO_LINGER

    SO_LINGER这个选项在我以前带队改造haproxy的时候引出过一个reset(RST)客户端连接的bug. SO_LINGER作用设置函数close()关闭TCP连接时的行为.缺省close() ...

  9. mysql 面试题 查询出表中某字段的重复值

    users 表中有 两个字段  id 和 name 表数据大概如下: id       name 1       AAA 2       BBB 3       CCC 4       AAA 请写查 ...

  10. 进行编译时提示'error: unrecognized command line option "-std=gnu11"'如何处理?

    答: 说明编译器不支持此选项,那么在Makefile中替换此选项-std=gnu11 替换成-std=gnu99或-std=c99或-std=c11等,主要看编译器都支持哪些编译选项,笔者的支持-st ...