多线程与CPU:
1.单核CPU  CPU密集型的程序(做计算操作的程序)  单线程即可( 此时的任务已经把CPU资源100%消耗了,就没必要也不可能使用多线程来提高计算效率)
2.单核CPU  IO密集型的程序(做IO操作的程序 )        多线程>单线程(多线程可以阻塞,但并不是并行,是“伪并行”,实际上还是一个CPU在执行一切事物,只是切换的太快,没法察觉)
3.多核CPU 做计算操作的程序 多线程>>单线程 (每个核心执行一个线程,每个核心的线程并发执行计算,以提高任务执行效率,例如加密解密,数据压缩解压缩(视频、音频、普通数据),否则只能使一个核心满载,而其他核心闲置。)

4.多核CPU  IO密集型任务 多线程>单线程

但是在PYTHON里:

由于GIL的机制就变得不完全一样了:单核CPU  CPU密集型程序 单线程耗时<多线程。多核CPU  CPU密集型程序 单线程耗时<多线程,也就是说只要是CPU密集型程序 不要只单独的使用多线程。

一、先说为什么会有GIL ,GIL是干什么的:

多线程之间数据完整性和状态同步的最简单方法自然就是加锁,于是python解释器有了GIL这把超级大锁,就默认python内部对象是thread-safe的,无需在实现时考虑额外的内存锁和同步操作。

也就是说 如果不释放这把锁,线程都是串行的。

但PYTHON的多线程并不是一无是处

二、GIL锁的释放机制:

先解释什么是IO密集型和计算密集型:

计算密集型任务的特点是要进行大量的计算,消耗CPU资源,比如计算圆周率、对视频进行高清解码等等,全靠CPU的运算能力。这种计算密集型任务虽然也可以用多任务完成,但是任务越多,花在任务切换的时间就越多,CPU执行任务的效率就越低,所以,要最高效地利用CPU,计算密集型任务同时进行的数量应当等于CPU的核心数。

计算密集型任务由于主要消耗CPU资源,因此,代码运行效率至关重要。Python这样的脚本语言运行效率很低,完全不适合计算密集型任务。对于计算密集型任务,最好用C语言编写。

第二种任务的类型是IO密集型,涉及到网络、磁盘IO的任务都是IO密集型任务,这类任务的特点是CPU消耗很少,任务的大部分时间都在等待IO操作完成(因为IO的速度远远低于CPU和内存的速度)。对于IO密集型任务,任务越多,CPU效率越高,但也有一个限度。常见的大部分任务都是IO密集型任务,比如Web应用。

IO密集型任务执行期间,99%的时间都花在IO上,花在CPU上的时间很少,因此,用运行速度极快的C语言替换用Python这样运行速度极低的脚本语言,完全无法提升运行效率。对于IO密集型任务,最合适的语言就是开发效率最高(代码量最少)的语言,脚本语言是首选,C语言最差。

GIL对于IO密集型和计算密集型:

IO密集型(网络传输、磁盘读写等):
线程遇到I/O阻塞时,会自动释放GIL。(阻塞等待时,就释放GIL,给另一个线程执行的机会)

cpu密集型(编解码,解压缩等):
解释器会周期性的让线程释放锁

由上面可知,至少有两种情况python会做线程切换,一是一但有IO操作时,会有线程切换,二是当一个线程连续执行了一定数量的指令时,会出现线程切换。

再加上每次操作系统执行线程的调度都需要消耗时间,这样,就可以理解为什么在多核+cpu密集型程序时不要单独的使用多线程,会比单线程更耗时。

即使是多核CPU,如果没有GIL 不同核的CPU执行不同的线程,但是有了GIL这把锁,某个核心上的CPU即使被唤醒也没有获得GIL锁,无法执行。

综上,在不使用别的库的情况下,python多线程最好只用于IO密集型的操作。

参考:https://blog.csdn.net/delacroix_xu/article/details/5928121   

       http://cenalulu.github.io/python/gil-in-python/

https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001397567993007df355a3394da48f0bf14960f0c78753f000

多线程与CPU和多线程与GIL的更多相关文章

  1. python2.0_s12_day9_协程&多线程和cpu,磁盘io之间的关系

    事件驱动和异步io有什么直接关系. 当我们访问一个网页,不考虑网络问题.我们人类不觉得网页慢. 但是实际中对计算机来说还是慢.那慢在哪里.io io操作是整个网络操作中最慢的.比如你打开网页要是有2秒 ...

  2. Java多线程(二)关于多线程的CPU密集型和IO密集型这件事

    点我跳过黑哥的卑鄙广告行为,进入正文. Java多线程系列更新中~ 正式篇: Java多线程(一) 什么是线程 Java多线程(二)关于多线程的CPU密集型和IO密集型这件事 Java多线程(三)如何 ...

  3. 【转】浅谈多核CPU、多线程、多进程

    浅谈多核CPU.多线程.多进程 1.CPU发展趋势 核心数目依旧会越来越多,依据摩尔定律,由于单个核心性能提升有着严重的瓶颈问题,普通的桌面PC有望在2017年末2018年初达到24核心(或者16核3 ...

  4. 002_Python多线程相当于单核多线程的论证

    很多人都说python多线程是假的多线程!下面进行论证解释: 一. 我们先明确一个概念,全局解释器锁(GIL) Python代码的执行由Python虚拟机(解释器)来控制.Python在设计之初就考虑 ...

  5. [.net 面向对象程序设计进阶] (16) 多线程(Multithreading)(一) 利用多线程提高程序性能(上)

    [.net 面向对象程序设计进阶] (16) 多线程(Multithreading)(一) 利用多线程提高程序性能(上) 本节导读: 随着硬件和网络的高速发展,为多线程(Multithreading) ...

  6. 多线程系列之 Java多线程的个人理解(一)

    前言:多线程常常是程序员面试时会被问到的问题之一,也会被面试官用来衡量应聘者的编程思维和能力的重要参考指标:无论是在工作中还是在应对面试时,多线程都是一个绕不过去的话题.本文重点围绕多线程,借助Jav ...

  7. 三、多线程基础-自旋_AQS_多线程上下文

    1. 自旋理解    很多synchronized里面的代码只是一些很简单的代码,执行时间非常快,此时等待的线程都加锁可能是一种不太值得的操作,因为线程阻塞涉及到用户态和内核态切换的问题.既然sync ...

  8. [.net 面向对象程序设计进阶] (18) 多线程(Multithreading)(三) 利用多线程提高程序性能(下)

    [.net 面向对象程序设计进阶] (18) 多线程(Multithreading)(二) 利用多线程提高程序性能(下) 本节导读: 上节说了线程同步中使用线程锁和线程通知的方式来处理资源共享问题,这 ...

  9. [.net 面向对象程序设计进阶] (17) 多线程(Multithreading)(二) 利用多线程提高程序性能(中)

    [.net 面向对象程序设计进阶] (17) 多线程(Multithreading)(二) 利用多线程提高程序性能(中) 本节要点: 上节介绍了多线程的基本使用方法和基本应用示例,本节深入介绍.NET ...

随机推荐

  1. python基础第一天 3.27

    # #作业1# 猜年龄,可以让用户猜三次!age = 25user_guess = int(input("input your guess"))   age = 25count = ...

  2. git版本控制系统更新

    版本控制系统: 一.概念: 版本控制系统(Version Control System):是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统. 二.版本控制系统分类 1.本地版本控制 ...

  3. 20145338 《网络对抗》 MSF基础应用

    20145338<网络对抗> MSF基础应用 实验内容 ·掌握metasploit的基本应用方式,掌握常用的三种攻击方式的思路. 具体需要完成(1)一个主动攻击;(2)一个针对浏览器的攻击 ...

  4. linux 迁移项目ProtocolException

    背景:服务器跟换机房,虚拟机完整迁移项目,只修改ip和主机名 1.检查/etc/hosts 中ip 和主机名映射 2.检查网络端口是否有限制以及端口开放是否全了,检查ip有没有配对.RMI注册不上.

  5. LeetCode 102 二叉树的层次遍历

    题目: 给定一个二叉树,返回其按层次遍历的节点值. (即逐层地,从左到右访问所有节点). 例如:给定二叉树: [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 ...

  6. ecplise包的层次结构选择

    ecplise包的层次结构选择 平坦方式: 分层方式:

  7. JavaWeb基础-Jsp内置对象

    request对象 客户端的请求信息被封装在request对象中,通过它才能了解到客户的需求,然后做出响应,它是HttpServlteRequest类的实例.Request对象具有请求域,即完成客户端 ...

  8. jsp页面传中文到后台乱码怎么办?

    一般从前台传值到后腰如果传的值是中文的话,又不用post传值方式,到后台显示会显示成乱码的形式.所以以下方法亲测有效防止乱码. 前台jsp页面: var taskTitle = $('#taskTit ...

  9. Docker桥接宿主机网络与配置固定IP地址

    有些需求是把这个容器与宿主机在同一个网段,但是本人不建议这样子去操作,因为一个容器本身就是一个封装好的服务.建议去按默认的网络去实现. 临时设置 [root@linux-docker01 ~]# vi ...

  10. Vmware Vsan 部署中如何将非SSD 硬盘标识为SSD

    通过SSH 登录ESXi主机 # esxcli storage nmp device list #查询ESXI 发现的存储设备 #   esxcli storage nmp satp rule add ...