<转>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. ...
随机推荐
- [SQL Server 系] -- 模糊查询
SQL Server中的通配符有下面四种 通配符 说明 % 包含零个或多个字符的任意字符串 _(下划线) 任意单个字符 [ ] 任意在指定范围或集合中的单个字符 [^ ] 任意不在指定范围或集合中的单 ...
- struts2学习笔记(2)——简单的输入验证以及标签库的运用
struts2自带了一些标签库,运用好这些标签库会减少开发周期. 1.struts2标签库是在哪定义的? struts2标签库定义在struts2-core-2.1.8.jar这个文件中,具体在这个j ...
- lintcode 容易题:Partition Array by Odd and Even 奇偶分割数组
题目: 奇偶分割数组 分割一个整数数组,使得奇数在前偶数在后. 样例 给定 [1, 2, 3, 4],返回 [1, 3, 2, 4]. 挑战 在原数组中完成,不使用额外空间. 解题: 一次快速排序就可 ...
- ipconfig
当使用ipconfig时不带任何参数选项,那么它为每个已经配置了的接口显示IP地址.子网掩码和缺省网关值. 如果你安装了虚拟机和无线网卡的话,它们的相关信息也会出现在这里.
- s.charAt()
public class ish{public static void main(String[]args){ String s="call me ishmae";System.o ...
- c# FastReport开发报表
本文介绍c#应用FastReport开发报表,因此首先附该工具下载地址:http://download.csdn.net/detail/hws1058648831a/6378499 下载解压后可以直接 ...
- OPENGL画图类库
链接 https://www.opengl.org/wiki/Language_bindings http://blog.csdn.net/luozhuang/article/details/421 ...
- DataGridView控件的使用---添加行
最简单的方法 可以静态绑定数据源,这样就自动为DataGridView控件添加相应的行. 假如需要动态为DataGridView控件添加新行,方法有很多种,下面简单介绍如何为DataGridView控 ...
- System,Integer,Calendar,Random和容器
System 1)arraycopy int[] a = {1.2.3.4}; int[] b = new int[5]; System.arraycopy(a,1,b,3,2); //把数组a中从下 ...
- Webbrowser模拟百度一下子点击事件
Webbrowser模拟百度一下点击事件新建一个form,有一个button和一个webbrowser控件.然后webbrowser一开始加载的就是百度主页.然后在文本框里输入点东西,如何做到点击bu ...