GIL:全局解释器锁 VS 用户程序锁
既然有了GIL锁,CPython还要多线程干什么?
'''
GIL:全局解释器锁的来历
四核:同一时刻真正有四个任务在运行,多核的意义在于此
单核:看上去是并发的,因为进行了上下文切换,单核永远是串行的,并发是假象
CPython中不论有多少核,只有一个核心的CPU资源被使用,因为同一时间只有一个线程能拿到GIL锁。
为什么这样设计呢?CPython的线程是调用操作系统的c语言的原生线程,该线程不是线程安全的。balabalabala...
===================官方解释======================
在CPython中,全局解释器锁或GIL是一个互斥锁,
这个锁是必要的,主要是因为CPython的内存管理不是线程安全的。
(然而,由于GIL的存在,其他特征已经发展成依赖于这个锁形成的线程安全环境)
=================================================
由于GIL是全局的,所以在多线程(多核)时,线程需满足两个条件才能执行
1、被操作系统调度出来【操作系统允许它占用CPU】 2、获取到GIL锁【CPython解释器允许它执行指令】
怎样避免GIL影响性能?就是减少GIL锁对线程的影响
1、在单核机器上Python和其他语言一样,“多线程”只是是假象实际上还是单线程。第2条总能满足,性能没有影响
2、在多核机器上Python只有一个核心在使用。因为多核多线程中,同时只有一个线程申请到GIL。所以要尽量减少
对GIL的申请,例如:全IO密集型任务时才使用多线程,
避免在计算密集型任务中使用Python的多线程(因为计算需要CPU资源,会频繁申请GIL锁,造成其他线程等待)
================================================
用户程序锁:
还有一个锁,用户程序锁,跟GIL没有关系。这个锁是保证某个全局变量的修改必须是串行的
假设有全局变量num=0,线程作用是对num执行加1的操作。
在线程调度的时候,A线程获取到num=0,A执行到一半,CPU执行B线程,
B线程将num修改num=1,CPU继续执行A线程,A线程执行完毕,将num修改成1,而num在AB线程执行完其实应该为2
此时就应该对num变量加锁。这个锁就是用户程序锁,这个锁不同于GIL锁。GIL锁是同一时间只能有一个线程使用
CPU资源,要保证同一时间只有一个线程访问某块数据就需要“用户程序锁”
=====================================================
在Python2.x版本+某些操作系统里不加用户程序锁会导致结果不准。
在Python3.x版本+某些操作系统里不确定是否有同样的问题,但是最好加上。
'''
import threading
import time lock = threading.Lock()
class Foo:
num = 0
@classmethod
def run(cls):
time.sleep(2)
lock.acquire()
cls.num += 1
lock.release()
thread_objs = []
for i in range(20):
thread_objs.append(threading.Thread(target=Foo.run, args=()))
start_time = time.time()
for i in thread_objs:
i.start()
for i in thread_objs:
i.join()
print(Foo.num) #
print(time.time()-start_time) # 2.0051145553588867
GIL:全局解释器锁 VS 用户程序锁的更多相关文章
- 【转】进程、线程、 GIL全局解释器锁知识点整理
转自:https://www.cnblogs.com/alex3714/articles/5230609.html 本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线 ...
- Python之路-python(paramiko,进程和线程的区别,GIL全局解释器锁,线程)
一.paramiko 二.进程.与线程区别 三.python GIL全局解释器锁 四.线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生 ...
- Python自动化 【第九篇】:Python基础-线程、进程及python GIL全局解释器锁
本节内容: 进程与线程区别 线程 a) 语法 b) join c) 线程锁之Lock\Rlock\信号量 d) 将线程变为守护进程 e) Event事件 f) queue队列 g) 生 ...
- GIL全局解释器锁
1. 什么是GIL全局解释器锁 GIL本质就是一把互斥锁,相当于执行权限,每个进程内都会存在一把GIL,同一进程内的多个线程 必须抢到GIL之后才能使用Cpython解释器来执行自己的代码,即 ...
- 网络编程-Python高级语法-GIL全局解释器锁
知识点:GIL全局解释器锁其实和Python没有任何关系,是由于当初编写Python解释器时留下的,它只对多线程有影响,GIL保证同一时刻只有一个线程在运行,即使是多核配置电脑,同一时刻也只会让一个线 ...
- 进程、线程与GIL全局解释器锁详解
进程与线程的关系: . 线程是最小的调度单位 . 进程是最小的管理单元 . 一个进程必须至少一个线程 . 没有线程,进程也就不复存在 线程特点: 线程的并发是利用cpu上下文的切换(是并发,不是并行) ...
- 关于python的GIL全局解释器锁的简单理解
GIL是解释器内部的一把锁,确切一点说是CPython解释器内部的一把锁,所以要注意区分 这和我们在Python代码中使用线程锁Lock并不是一个层面的概念. 1. GIL产生的背景: 在CPytho ...
- [py]GIL(全局解释器锁):多线程模式
在多线程 时同一时刻只允许一个线程来访问CPU,直到解释器遇到I/O操作或者操作次数达到一定数目时才会释放GIL 参考 Python虽然不能利用多线程实现多核任务,但可以通过多进程实现多核任务.多个P ...
- 10 并发编程-(线程)-GIL全局解释器锁&死锁与递归锁
一.GIL全局解释器锁 1.引子 在Cpython解释器中,同一个进程下开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势 首先需要明确的一点是GIL并不是Python的特性,它是在实现Pyt ...
随机推荐
- asp.net core 系列 16 Web主机 IWebHostBuilder
一.概述 在asp.net core中,Host主机负责应用程序启动和生存期管理.host主机包括Web 主机(IWebHostBuilder)和通用主机(IHostBuilder).Web 主机是适 ...
- HUSTOJ:Transit Tree Path
问题 D: Transit Tree Path You are given a tree with N vertices.Here, a tree is a kind of graph, and ...
- flag.xls
Topic Link http://ctf5.shiyanbar.com/misc/flag.xls 1) 打开表格发现需要密码 但是flag又在表里,但我们可以改他的格式为.txt文本,因为这样就 ...
- leetcode — path-sum
/** * Source : https://oj.leetcode.com/problems/path-sum/ * * * Given a binary tree and a sum, deter ...
- Mybatis动态SQL简单了解 Mybatis简介(四)
动态SQL概况 MyBatis 的强大特性之一便是它的动态 SQL 在Java开发中经常遇到条件判断,比如: if(x>0){ //执行一些逻辑........ } Mybatis应用中,S ...
- 超级账本fabric原理之gossip详解
Goosip协议 去中心化.容错和最终一致性的算法 信息达到同步的最优时间:log(N). 功能: 节点发现 数据广播 gossip中有三种基本的操作: push - A节点将数据(key,value ...
- IO通信模型(二)同步非阻塞模式NIO(NonBlocking IO)
同步非阻塞模式(NonBlocking IO) 在非阻塞模式中,发出Socket的accept()和read()操作时,如果内核中的数据还没有准备好,那么它并不会阻塞用户进程,而是立刻返回一个信息.也 ...
- Elasticsearch.net项目实战
elasticsearch.net项目实战 目录 Elasticsearch+kibana 环境搭建 windows 10环境配置 安装Elasticsearch head安装(非必需) 安装kiba ...
- TensorFlow资料汇总
升级mac自带的python 使用virtualenv进行python环境隔离 tf.nn.conv2d.卷积函数 max_pool 池化函数 TF.VARIABLE.TF.GET_VARIABLE. ...
- jsp基础语言-jsp动作
jsp动作是一组jsp内置的标签,用来控制jsp的行为,执行一些常用的jsp页面动作.通过jsp动作实现使用多行java代码能够实现的效果,即对常用的jsp功能进行抽象与封装. jsp共有七种标准的“ ...