在多线程 时同一时刻只允许一个线程来访问CPU,直到解释器遇到I/O操作或者操作次数达到一定数目时才会释放GIL

参考

Python虽然不能利用多线程实现多核任务,但可以通过多进程实现多核任务。多个Python进程有各自独立的GIL锁,互不影响。

启动与CPU核心数量相同的N个线程,在4核CPU上可以监控到CPU占用率仅有102%,也就是仅使用了一核。

但是用C、C++或Java来改写相同的死循环,直接可以把全部核心跑满,4核就跑到400%,8核就跑到800%,为什么Python不行呢?

因为Python的线程虽然是真正的线程,但解释器执行代码时,有一个GIL锁:Global Interpreter Lock,任何Python线程执行前,必须先获得GIL锁,然后,每执行100条字节码,解释器就自动释放GIL锁,让别的线程有机会执行。这个GIL全局锁实际上把所有线程的执行代码都给上了锁,所以,多线程在Python中只能交替执行,即使100个线程跑在100核CPU上,也只能用到1个核。

GIL是Python解释器设计的历史遗留问题,通常我们用的解释器是官方实现的CPython,要真正利用多核,除非重写一个不带GIL的解释器。

进程与线程模式

线程之间共享内存的两种处理方法:

  • 内存类型-厕所 "互斥锁"(Mutual exclusion,缩写 Mutex),防止多个线程同时读写某一块内存区域。 进厕所后上把锁.
  • 内存类型-澡堂 "信号量"(Semaphore),用来保证多个线程不会互相冲突。 领取牌进去洗澡.

GIL(全局解释器锁)

参考: http://www.cnblogs.com/iiiiiher/p/8341091.html

参考

我的机器有4核,代表着同一时间,可以干4个任务。如果单核cpu的话,我启动10个线程,我看上去也是并发的,因为是执行了上下文的切换,让我看上去是并发的。但是单核永远肯定时串行的,它肯定是串行的,cpu真正执行的时候,因为一会执行1,一会执行2.。。。。正常的线程就是这个样子的。但是,在python中,无论你有多少核,永远都是假象。无论你是4核,8核,还是16核.......不好意思,同一时间执行的线程只有一个(线程),它就是这个样子的。这个是python的一个开发时候,设计的一个缺陷,所以说python中的线程是假线程。

参考

GIL(全局解释器锁)

我们知道多进程(mutilprocess) 和 多线程(threading)的目的是用来被多颗CPU进行访问, 提高程序的执行效率。 但是在python内部存在一种机制(GIL),在多线程 时同一时刻只允许一个线程来访问CPU。

GIL 并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念。就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码。有名的编译器例如GCC,INTEL C++,Visual C++等。

Python也一样,同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行环境来执行。像其中的JPython就没有GIL。然而因为CPython是大部分环境下默认的Python执行环境。所以在很多人的概念里CPython就是Python,也就想当然的把 GIL 归结为Python语言的缺陷。所以这里要先明确一点:GIL并不是Python的特性,Python完全可以不依赖于GIL。

虽然python支持多线程,但是由于GIL的限制,在实际运行时,程序运行后开启多个线程,但在通过GIL后同时也只能有一个线程被CPU执行。

GIL(全局解释器锁)

参考: http://www.cnblogs.com/zephyr-1/p/6043785.html

GIL并不是Python的特性,他是CPython引入的概念,是一个全局排他锁。

解释执行python代码时,会限制线程对共享资源的访问,直到解释器遇到I/O操作或者操作次数达到一定数目时才会释放GIL。

所以,虽然CPython的线程库直接封装了系统的原生线程,但CPython整体作为一个进程,同一时间只会有一个获得GIL的线程在跑,其他线程则处于等待状态。这就造成了即使在多核CPU中,多线程也只是做着分时切换而已,所以多线程比较适合IO密集型,不太适合CPU密集型的任务。

同一时刻一个解释进程只有一行bytecode 在执行

python多线程为什么不能利用多核cpu

[py]GIL(全局解释器锁):多线程模式的更多相关文章

  1. python GIL全局解释器锁,多线程多进程效率比较,进程池,协程,TCP服务端实现协程

    GIL全局解释器锁 ''' python解释器: - Cpython C语言 - Jpython java ... 1.GIL: 全局解释器锁 - 翻译: 在同一个进程下开启的多线程,同一时刻只能有一 ...

  2. 网络编程之多线程——GIL全局解释器锁

    网络编程之多线程--GIL全局解释器锁 一.引子 定义: In CPython, the global interpreter lock, or GIL, is a mutex that preven ...

  3. python 并发编程 多线程 GIL全局解释器锁基本概念

    首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念. 就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码. ...

  4. [Python 多线程] GIL全局解释器锁 (十三)

    Queue 标准库queue模块,提供FIFO(先进先出)的Queue.LIFO(后进先出)的队列.优先队列. Queue类是线程安全的,适用于多线程间安全的交换数据.内部使用了Lock和Condit ...

  5. 并发编程~~~多线程~~~守护线程, 互斥锁, 死锁现象与递归锁, 信号量 (Semaphore), GIL全局解释器锁

    一 守护线程 from threading import Thread import time def foo(): print(123) time.sleep(1) print('end123') ...

  6. python并发编程-多线程实现服务端并发-GIL全局解释器锁-验证python多线程是否有用-死锁-递归锁-信号量-Event事件-线程结合队列-03

    目录 结合多线程实现服务端并发(不用socketserver模块) 服务端代码 客户端代码 CIL全局解释器锁****** 可能被问到的两个判断 与普通互斥锁的区别 验证python的多线程是否有用需 ...

  7. python多线程和GIL全局解释器锁

    1.线程     线程被称为轻量级进程,是最小执行单元,系统调度的单位.线程切换需要的资源一般,效率一般.  2.多线程         在单个程序中同时运行多个线程完成不同的工作,称为多线程 3.并 ...

  8. GIL全局解释器锁、死锁现象、python多线程的用处、进程池与线程池理论

    昨日内容回顾 僵尸进程与孤儿进程 # 僵尸进程: 所有的进程在运行结束之后并不会立刻销毁(父进程需要获取该进程的资源) # 孤儿进程: 子进程正常运行 但是产生该子进程的父进程意外死亡 # 守护进程: ...

  9. Python之路-python(paramiko,进程和线程的区别,GIL全局解释器锁,线程)

    一.paramiko 二.进程.与线程区别 三.python GIL全局解释器锁 四.线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生 ...

随机推荐

  1. IOS设计模式第四篇之装饰设计模式的类别设计模式

    装饰设计模式 装饰设计模式动态的添加行为和责任向一个对象而不修改他的任何代码.他是你子类化修改类的行为用通过另一个对象的包装的代替方法. 在Objective-c里面有很多这种设计模式的实现,像cat ...

  2. 【资源大全】.NET资源大全中文版(Awesome最新版)

    算法与数据结构(Algorithms and Data structures) 应用程序接口(API) 应用程序框架(Application Frameworks) 模板引擎(Application ...

  3. C#项目学习 心得笔记本

    CacheDependency 缓存 //创建缓存依赖项 CacheDependency dep = new CacheDependency(fileName); //创建缓存 HttpContext ...

  4. Cracking the Coding Interview(linked list)

    第二章的内容主要是关于链表的一些问题. 基础代码: class LinkNode { public: int linknum; LinkNode *next; int isvisit; protect ...

  5. 【CF662C】Binary Table 按位处理

    [CF662C]Binary Table 题意:给你一个$n\times m$的01网格,你可以进行任意次操作,每次操作是将一行或一列的数都取反,问你最多可以得到多少个1? $n\le 20,m\le ...

  6. SOA架构商城二 框架搭建

    1.创建父工程 创建Maven工程pingyougou-parent,选择packaging类型为pom ,在pom.xml文件中添加锁定版本信息dependencyManagement与plugin ...

  7. mysql 外键 cascade

    1 . cascade方式在父表上update/delete记录时,同步update/delete掉子表的匹配记录 2. set null方式在父表上update/delete记录时,将子表上匹配记录 ...

  8. 美团开源 SQL 优化工具 SQLAdvisor

    https://www.oschina.net/news/82725/sqladvisor-opensource https://github.com/Meituan-Dianping/SQLAdvi ...

  9. 解析xml文件的几种技术与Dom4j与sax之间的对比

    一.解析xml文件的几种技术:dom4j.sax.jaxb.jdom.dom 1.dom4j dom4j是一个Java的XML API,类似于jdom,用来读写XML文件的.dom4j是一个非常优秀的 ...

  10. vs2010版本注释

    转:http://www.cnblogs.com/chaselwang/p/3580839.html 关于Visual Studio 20**自动添加头部注释信息 作为一个万年潜水党,不关这一篇文章技 ...