<转>Python 多线程的单cpu与cpu上的多线程的区别
你对Python 多线程有所了解的话。那么你对python 多线程在单cpu意义上的多线程与多cpu上的多线程有着本质的区别,如果你对Python 多线程的相关知识想有更多的了解,你就可以浏览我们的文章。
Python多线程是单cpu意义上的多线程,它和多cpu上的多线程有着本质的区别。
单cpu多线程:并发
多cpu多线程:并行内部包含并发
在Python 多线程当中,存在一个叫Global Interpreter Lock(GIL)的东西,直译就是全局解释器锁。它的作用在于让同一时刻只能有一个线程对于python对象进行操作。Python已经提供了各种机制让我们进行多线程同步,为什么又要整这个GIL呢?这是因为程序员控制的同步是对各个程序中可见的变量,而GIL同步的是解释器后台的不可见变量,比如为了进行垃圾回收而维护的引用计数。如果没有GIL,有可能出现由于线程切换导致的对同一个对象释放两次的情况。
因此,任何一个CPython线程如果要执行,就必须先获取这个GIL。后果?就是在CPython中,本质上几乎是没有线程并行的,不论你开多少个线程,同一时刻只有获取GIL的那个线程能够执行。为什么要说几乎呢,这是因为提供给python的C库中,还是有解决方案的,比如
这段代码是sleep的代码,在执行sleep之前,通过一个宏来释放GIL,然后在睡眠结束执行其他代码前又获取GIL。其他一下操作,比如IO,也会有类似的操作,这样就使得对于IO密集型的程序,或者是使用C库进行计算的程序,还是可以在很大程度上避开GIL来取得线程并行的效果的。但对于纯python代码的程序,GIL恐怕还是躲不过去的。
还有一个问题,就是GIL怎么释放,我们看到在python/C API中提供了宏来进行释放,那么对于普通的python语句呢?解释器会在执行一百条python代码后强制释放GIL,这就使得其它线程得以执行。
最后需要说明的,就是这个GIL的问题是解释器相关的,而不是语言相关的。也就是说它只是对于python语言解释器的一种实现,并不是语言本身的特性。事实上,GIL就是解释器的一个非常粗粒度的锁,我们完全可以采用更细粒度的锁来增加并行性,而且Gindo就写过一个patch来取消GIL,不过好像最后的结果是细粒度锁导致了单线程程序的性能下降了两倍,所以最后还是决定优先保证单线程程序的性能,继续保留GIL。但是python的其他两个分支,Jython和IronPython,却都没有GIL的问题,从而可以实现线程的并行。
总结:
通常加锁也有2种不同的粒度的锁:
fine-grained(所谓的细粒度), 那么程序员需要自行地加,解锁来保证线程安全
coarse-grained(所谓的粗粒度), 那么语言层面本身维护着一个全局的锁机制,用来保证线程安全
Python 多线程 从语言层面本身维护着一个全局的锁机制,用来保证线程安全;而java, Jython则是细粒度的。
所以也就是说,由于gil的限制,python语言本身是不能够进行并行编程的,但是可以进行并发编程;而java则没有gil意义上的限制,因此java从java7开始已经开始往并行上偏移了。
<转>Python 多线程的单cpu与cpu上的多线程的区别的更多相关文章
- python 里面的单下划线与双下划线的区别
python 里面的单下划线与双下划线的区别 Python 用下划线作为变量前缀和后缀指定特殊变量. _xxx 不能用'from moduleimport *'导入 __xxx__ 系统定义名字 __ ...
- python 里面的单下划线与双下划线的区别(私有和保护)
Python 用下划线作为变量前缀和后缀指定特殊变量. _xxx 不能用'from moduleimport *'导入 __xxx__ 系统定义名字 __xxx 类中的私有变量名 核心风格:避免用下划 ...
- python多线程为什么不能利用多核cpu
GIL 与 Python 线程的纠葛 GIL 是什么东西?它对我们的 python 程序会产生什么样的影响?我们先来看一个问题.运行下面这段 python 程序,CPU 占用率是多少? # 请勿在工作 ...
- python GIL 全局锁,多核cpu下的多线程性能究竟如何?
python GIL 全局锁,多核cpu下的多线程性能究竟如何?GIL全称Global Interpreter Lock GIL是什么? 首先需要明确的一点是GIL并不是Python的特性,它是在实现 ...
- [深度学习] Pytorch(三)—— 多/单GPU、CPU,训练保存、加载模型参数问题
[深度学习] Pytorch(三)-- 多/单GPU.CPU,训练保存.加载预测模型问题 上一篇实践学习中,遇到了在多/单个GPU.GPU与CPU的不同环境下训练保存.加载使用使用模型的问题,如果保存 ...
- Python之路第十天,高级(2)-多线程,多进程,协程
线程 threading threading模块对象 描述 Thread 表示一个线程的执行对象 Lock 锁原语对象 RLock 可重入锁对象,使单线程可再次获得已经获得了的锁(递归锁定) Cond ...
- JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制
JAVA之旅(十四)--静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制 JAVA之旅,一路有你,加油! 一.静态同步函数的锁是clas ...
- [svc][cpu][jk]cpu的核心查看及什么是cpu的负载
监控的时候我们会监控cpu的负载,那么什么是负载? 编程时候有多核多线程的概念,那么cpu内部如何运作的? 搞清多少bit cpu? 有几个物理cpu?每个cpu是几核的? 之前购买内存条时候,需要关 ...
- CPU | 物理 CPU vs 逻辑 CPU vs 核心 vs 线程 vs Socket
当我们试着通过 Linux 命令 nproc 和 lscpu 了解一台计算机 CPU 级的架构和性能时,我们总会发现无法正确地理解相应的结果,因为我们会被好几个术语搞混淆:物理 CPU.逻辑 CPU. ...
随机推荐
- 李洪强iOS开发之让您的Xcode键字如飞
手指在键盘上飞速跳跃,终端上的代码也随着飞舞,是的这确实很酷.优秀的程序员总是这么一群人,他们不拘于现状,不固步自封,他们喜欢新奇的事,他们把自己发挥到极致. 指法攻略 放下您钟爱的鼠标吧,在前行之中 ...
- lintcode: 二叉查找树中搜索区间
题目 二叉查找树中搜索区间 给定两个值 k1 和 k2(k1 < k2)和一个二叉查找树的根节点.找到树中所有值在 k1 到 k2 范围内的节点.即打印所有x (k1 <= x <= ...
- Python图片与其矩阵数据互相转换
程序 # coding=gbk from PIL import Image import numpy as np # import scipy import matplotlib.pyplot as ...
- 让Windows蓝屏死机
ssdt 随便一个函数入口改90就蓝了 ------------------------------------------------- program Project2; uses Windows ...
- Java API —— 编码 & IO流( InputStreamReader & OutputStreamWriter & FileReader & FileWriter & BufferedReader & BufferedWriter )
1.编码 1)编码表概述 由字符及其对应的数值组成的一张表 2)常见编码表 · ASCII/Unicode 字符集:ASCII是美国标准信息交换码,用一 ...
- HDU 4604 deque 最长上升子序列
枚举每个位置,求以num[i]为起点的最长不下降子序列和以num[i]为结尾的最长不递增子序列. 并且把相同值的个数统计一下,最后要减去算重复了的. 比如: 1 9 4 4 2 2 2 3 3 3 7 ...
- 富有魅力的git stash
git stash 会把当前的改动暂时搁置起来, 也就是所谓的git 暂存区. 你可以执行 git stash list 来查看你所有暂存的东东. 也可以 git stash apple ** 来拿下 ...
- CY7C68013A的一点总结
一. 值得参考的资料:FX2 TechRefManual.USB应用开发宝典. LabVIEW-USB通信简单教程(用于参考生成labview驱动程序).USB设备请求和描述符整理(仅用于理解描述符的 ...
- Android软件开发需要学什么
首先,需要学习哪些Android开发技术? Android的开发技术很多,在开始学习的时候不可能一次性全部学会,也没有必要一开始都全部学会,但是有些技术是非常常用的,需要在开始时打好基础,这些技术时: ...
- HDU 1280 前m大的数【哈希入门】
题意:中文的题目= =将各种组合可能得到的和作为下标,然后因为不同组合得到的和可能是一样的, 所以再用一个数组num[]数组,就可以将相同的和都记录下来 #include<iostream> ...