python中的多线程 GIL(全局解释器锁) 死锁与递归锁
1.什么的是线程
在程序里一个执行路线就叫做线程,线程是程序执行的最小单位
2.多线程的优点
- 使用线程可以把占据长时间的程序中的任务放到后台去处理。
- 在处理I/O密集程序的运行速度可能加快(ps:计算型密集任务除外)
- 在一些等待的任务实现上如用户输入、文件读写和网络收发数据等。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。
- 线程可以被抢占(中断)。
- .在其他线程正在运行时,线程可以暂时搁置(也称为睡眠) – 这就是线程的退让
3.多线程的缺点
- 无法使用多核,由于gil锁的存在,他只能一个一个的取抢锁
- 多线程对I/O 有效果,对于需要cpu计算的时候,反复切换会浪费时间反而会降低效率
- 同时操作同一个共享资源,所以造成了资源破坏,即线程不安全
总结:
Python 多线程并发,可以提高 i/o 密集型程序的运行效率,但对于计算密集型程序, Python
多线程并发并不能显著提升效率(并非是不适合使用,因为鬼知道现实世界会有什么样的应用场景)
4.python实现简单的多线程
Python3 通过两个标准库 _thread 和 threading 提供对线程的支持,由于_thread只是为了兼容python2的thread模块,所以推荐使用threading模块实现多线程。
threading提供了如下方法:
- run(): 用以表示线程活动的方法。
- start():启动线程活动。
- join([time]): 等待到线程中止。
- isAlive(): 返回线程是否活动的。
- getName(): 返回线程名。
- setName(): 设置线程名。
#导入线程模块
import threading
#导入时间模块
import time#唱歌
def singing():for i in range(1,21):print("我会唱歌~~~ %d" %i)time.sleep(0.5)#跳舞
def dancing():for i in range(1,21):print("我会跳舞^^^ %d" %i)time.sleep(0.5)#打篮球
def play_basketball():for i in range(1,21):print("我还会打篮球··· %d" %i)time.sleep(0.5)#练习
def practise():for i in range(1,21):print("我是来自美国,练习时长两年半的练习生$$$ %d" %i)time.sleep(0.5)def main():"""创建启动线程"""t_singing = threading.Thread(target=singing)t_dancing = threading.Thread(target=dancing)t_play_basketball = threading.Thread(target=play_basketball)t_practise = threading.Thread(target=practise)t_singing.start()t_dancing.start()t_play_basketball.start()t_practise.start()if __name__ == '__main__':main()
结果:
我是来自美国,练习时长两年半的练习生$$$ 1
我会唱歌~~~ 2我会跳舞^^^ 2我是来自美国,练习时长两年半的练习生$$$ 2
我还会打篮球··· 2
我会唱歌~~~ 3
我会跳舞^^^ 3
我还会打篮球··· 3
我是来自美国,练习时长两年半的练习生$$$ 3
我会唱歌~~~ 4
我会跳舞^^^ 4
我还会打篮球··· 4
我是来自美国,练习时长两年半的练习生$$$ 4
我会跳舞^^^ 5
我会唱歌~~~ 5
我是来自美国,练习时长两年半的练习生$$$ 5
5.GIL(Global Interpreter Lock)全局解释器锁
在非python环境中,单核情况下,同时只能有一个任务执行。多核时可以支持多个线程同时执行。但是在python中,无论有多少核,同时只能执行一个线程。究其原因,这就是由于GIL的存在导致的。
GIL的全称是Global Interpreter Lock(全局解释器锁),来源是python设计之初的考虑,为了数据安全所做的决定。某个线程想要执行,必须先拿到GIL,我们可以把GIL看作是“通行证”,并且在一个python进程中,GIL只有一个。拿不到通行证的线程,就不允许进入CPU执行。GIL只在cpython中才有,因为cpython调用的是c语言的原生线程,所以他不能直接操作cpu,只能利用GIL保证同一时间只能有一个线程拿到数据。而在pypy和jpython中是没有GIL的。
6.Python多线程的工作过程:
python在使用多线程的时候,调用的是c语言的原生线程。
- 拿到公共数据
- 申请gil
- python解释器调用os原生线程
- os操作cpu执行运算
- 当该线程执行时间到后,无论运算是否已经执行完,gil都被要求释放
- 进而由其他进程重复上面的过程
- 等其他进程执行完后,又会切换到之前的线程(从他记录的上下文继续执行),整个过程是每个线程执行自己的运算,当执行时间到就进行切换(context
switch)。
简述:
线程锁的意义
当多个线程同时修改同一条数据时可能会出现脏数据,所以,出现了线程锁,即同一时刻允许一个线程执行操作。
也就是为了解决线程不安全问题
死锁和递归锁
什么是死锁:就是两个线程都等待对方释放资源。
案例:
#死锁
from threading import Thread,Lock
import time
mutexA = Lock()
mutexB = Lock()class Work(Thread):def run(self):self.f1()self.f2()def f1(self):mutexA.acquire()print('%s 拿到了A锁 ' % self.name)mutexB.acquire()print('%s拿到了B锁' % self.name)mutexB.release()print('%s 释放了 B锁' % self.name)mutexA.release()print('%s 释放了 A锁' % self.name)def f2(self):mutexB.acquire()time.sleep(2)print('%s 拿到了B锁 ' % self.name)mutexA.acquire()print('%s拿到了A锁' % self.name)mutexA.release()print('%s 释放了 A锁' % self.name)mutexB.release()print('%s 释放了 B锁' % self.name)if __name__ == '__main__':for i in range(5):t = Work()t.start()
结果:
Thread-1 拿到了A锁
Thread-1拿到了B锁
Thread-1 释放了 B锁
Thread-1 释放了 A锁
Thread-2 拿到了A锁
Thread-1 拿到了B锁
递归锁
递归锁:Rlock
Rlock内部有一个count 初始为0 ,锁一下加1,释放了就减1
#递归锁
from threading import Thread,RLock
import time
mutexA = mutexB = RLock()
class Work(Thread):def run(self):self.f1()self.f2()def f1(self):mutexA.acquire()print('%s 拿到了A锁 ' % self.name)mutexB.acquire()print('%s拿到了B锁' % self.name)mutexB.release()print('%s 释放了 b锁' % self.name)mutexA.release()print('%s 释放了 a锁' % self.name)def f2(self):mutexB.acquire()time.sleep(2)print('%s 拿到了A锁 ' % self.name)mutexA.acquire()print('%s拿到了B锁' % self.name)mutexA.release()print('%s 释放了 b锁' % self.name)mutexB.release()print('%s 释放了 a锁' % self.name)if __name__ == '__main__':for i in range(3):t = Work()t.start()
结果:
Thread-1 拿到了A锁
Thread-1拿到了B锁
Thread-1 释放了 b锁
Thread-1 释放了 a锁
Thread-1 拿到了A锁
Thread-1拿到了B锁
Thread-1 释放了 b锁
Thread-1 释放了 a锁
Thread-2 拿到了A锁
Thread-2拿到了B锁
Thread-2 释放了 b锁
Thread-2 释放了 a锁
Thread-2 拿到了A锁
Thread-2拿到了B锁
Thread-2 释放了 b锁
Thread-2 释放了 a锁
Thread-3 拿到了A锁
Thread-3拿到了B锁
Thread-3 释放了 b锁
Thread-3 释放了 a锁
Thread-3 拿到了A锁
Thread-3拿到了B锁
Thread-3 释放了 b锁
Thread-3 释放了 a锁
python中的多线程 GIL(全局解释器锁) 死锁与递归锁相关推荐
- gil php,网络编程之多线程——GIL全局解释器锁
网络编程之多线程--GIL全局解释器锁 一.引子 定义: In CPython, the global interpreter lock, or GIL, is a mutex that preven ...
- 多线程—— GIL(全局解释器锁)
文章目录 1.前言 2.测试 GIL 1.前言 python 的多线程 threading 有时候并不是特别理想. 最主要的原因是就是, Python 的设计上, 有一个必要的环节, 就是 Globa ...
- Python中的GIL(全局解释器锁)
1. GIL全称Global Interpreter Lock,每个线程在执行的过程都需要先获取GIL,保证同一时刻只有一个线程可以执行代码. 2.GIL的缺点 GIL使Python不能充分利用多核心 ...
- python GIL :全局解释器
cpython 解释器中存在一个GIL(全局解释器锁),无论多少个线程.多少颗cpu 他的作用就是保证同一时刻只有一个线程可以执行代码,因此造成了我们使用多线程的时候无法实现并行. 因为有GIL的存在 ...
- Python之路 34:并发与并行、锁(GIL、同步锁、死锁与递归锁)、信号量、线程队列、生消模型、进程(基础使用、进程通信、进程池、回调函数)、协程
内容: 同步锁 死锁.递归锁 信号量和同步对象(暂时了解即可) 队列------生产者和消费者模型 进程(基础使用.进程通信.进程池.回调函数) 协程 一.并发并行与同步异步的概念 1.1.并发和并行 ...
- android 线程互斥锁,线程锁(互斥锁Mutex)及递归锁
一.线程锁(互斥锁) 在一个程序内,主进程可以启动很多个线程,这些线程都可以访问主进程的内存空间,在Python中虽然有了GIL,同一时间只有一个线程在运行,可是这些线程的调度都归系统,操作系统有自身 ...
- 互斥锁、死锁、递归锁、信号量、Event
互斥锁 死锁和递归锁 Semaphore信号量 Event事件 互斥锁 互斥锁也叫用户锁.同步锁. 在多进程/多线程程序中,当多个线程处理一个公共数据时,会有数据安全问题,唯一能保证数据安全的,就是通 ...
- python gil 解除_详解Python中的GIL(全局解释器锁)详解及解决GIL的几种方案
先看一道GIL面试题: 描述Python GIL的概念, 以及它对python多线程的影响?编写一个多线程抓取网页的程序,并阐明多线程抓取程序是否可比单线程性能有提升,并解释原因. GIL:又叫全局解 ...
- python多线程为啥是假的?(GIL 全局解释器锁)(python多线程不适合并行化的计算密集型代码)
1. 问: 答: 2. from threading import Thread def loop(): while True: print("亲爱的,我错了,我能吃饭了吗?&quo ...
最新文章
- java并行安全吗_并发和并行有什么区别
- CodeBlocks主题和字体
- 网络推广方法带你了解优质的网站结构对网站SEO有什么好处?
- Hadoop的安装(单机和集群)
- 为Pdf批量添加水印
- 20位大佬组团“踢馆”,谁超越了图灵?
- linux-基本权限UGO-读写执行权限
- 使用Docker启动Kafka-Manager
- Bootstrap进度条堆叠
- 程序员除了编代码,还能做哪些职业规划?
- 【Python】Python中文编码
- web.xml中配置启动时加载的servlet,load-on-starup
- 注册ActiveX控件时DllRegisterServer调用失败的解决方法
- Datawhale组队学习周报(第030周)
- 我走进了微缩的“物联国”
- 330tsl是什么意思_19款探岳330tsl两区豪华型怎么样?
- 微信用户提现功能 显示NO_AUTH | 产品权限验证失败,请查看您当前是否具有该产品的权限(企业付款到零钱 银行卡)
- 创建进程-CreateProcess (一)
- AM335x SPL(一)
- Camera AF和FF
热门文章
- getchar 和 getch区别
- 2021-04-28-飞机大战-001-day5-游戏滚动背景
- 说话中的引题技巧,及电影刘三姐中的歌词汇总
- 解决vs2013+wdk7 编译nt系统wdm驱动 error C2220: 警告被视为错误 - 没有生成“object”文件
- Android 发布代码到github 并且部署到 JitPack maven 仓库详细步骤
- 使用java.awt.Robot实现java版的自动点击事件
- Java程序设计——随机点名器
- 这些好用的跨境电商插件,你都听说几个?
- 2021河南科技大学计算机考研科目,2021河南科技大学考研参考书目
- IoC容器和 Dependency Injection模式 Inversion of Control Containers and the Dependency Injection pattern