python多线程

day_31

感情迁移 提交于 2019-12-02 05:51:21
昨日回顾 GIL全局解释锁 python解释器 Cpython(C语言编写) Jpython(Java编写) Ppython(Python编写) GIL全局解释锁 基于CPython来研究全局解释器锁,因为CPython的内存线程不是安全的 GIL本质上是一个互斥锁 GIL是为了阻止同一个进程内多个线程同时执行(并行) GIL的存在就是为了保证线程安全 注意:多个线程过来执行,一旦遇到IO操作,就会立马释放GIL解释器锁,交给下一个先进来的线程 多线程的作用 计算密集型程序 在单核情况下,若一个任务需要10s 开启进程,消耗资源大,执行4个进程需要40s 开启线程,消耗资源小,执行4个线程需要40s 在多核情况下,若一个任务需要10s 开启进程,并行执行,效率较高,执行4个进程需要10s 开启线程,并发执行,效率较低,执行4个线程需要40s IO密集型程序 在单核情况下,若一个任务需要10s 开启进程,消耗资源大,执行4个进程需要40s 开启线程,消耗资源小,执行4个线程需要40s 在多核情况下,若一个任务需要10s 开启进程,并行执行,效率小于线程,因为遇到IO会立即切换CPU执行权限,执行4个进程需要10s = 开启进程的额外时间 开启线程,并发执行,效率高于进程,执行4个线程需要40s 死锁现象 死锁是指两个或两个以上的进程或线程在执行过程中

Python GIL全局解释器锁

独自空忆成欢 提交于 2019-12-02 05:38:10
GIL解释: GIL:Global Interpreter Lock 全局解释器锁,设计目的是保证数据安全。 GIL 的功能是:在 CPython 解释器中执行的每一个 Python 线程,都会先锁住自己,以阻止别的线程执行。也就是说在解释器执行任何Python代码时,都需要先获取这把锁,意味着 任何时候只可能有一个线程在执行代码,其他线程要想获得CPU去执行代码,就必须等到占有该锁的线程释放锁才有执行的可能。 当然Python中不会让一个线程一直独占解释器,它会轮流执行 Python 线程,即 Python 线程在交替执行,来模拟真正并行的线程(伪并行),但 Python中每次释放GIL锁,线程进行锁竞争、切换线程,都会造成资源消耗, 并且由于GIL锁存在,python里一个进程永远只能同时执行一个线程(拿到GIL的线程才能执行) ,导致在多核CPU上,Python的多线程效率并不高。 如果所示,三个线程交替执行,借此模拟并行。但某一时刻,程序中只有一个线程在执行,其他线程在等待其释放锁。 GIL 的特点: 1. Python在多线程下,每个线程的执行方式为: 获取GIL 执行代码直到sleep或者是python虚拟机将其挂起。 释放GIL 2. 一个CPU只能执行一个线程 ,例如一个CPU 有三个线程 ,首先线程A执行 ,然后 线程A达到释放条件进行释放GIL,线程B 和线程C

day 30

一世执手 提交于 2019-12-02 04:52:29
目录 GIL(全局解释器锁) 多线程的作用 死锁现象 递归锁 RLock 信号量 线程队列 GIL(全局解释器锁) 在CPython中,全局解释器锁(GIL)是一个防止多个锁的互斥锁。 本机线程从执行Python字节码一次。这把锁主要是必须的因为CPython的内存管理不是线程安全。(然而,自从GIL存在时,其他功能已逐渐依赖于它所实施的保证。) 基于CPython来研究全局解释器锁 ​ 1.GIL本质是一个互斥锁 ​ 2.GIL是为了阻止同一个进程内多个线程同时执行(并行) ​ — 单个进程下的多个线程无法实现并行,但能实现并发 ​ 3.这把锁主要是因为CPython的内存管理不是"线程安全"的 ​ — 内存管理 ​ — 垃圾回收机制 ​ 注意:多个线程过来执行,一旦遇到IO操作,就会立马释放GIL解释器锁,交给下一个先进来的线程 import time from threading import Thread, current_thread number = 100 def task(): global number number2 = number # time.sleep(1) number = number2 - 1 print(number, current_thread().name) for line in range(100): t = Thread(target

day30

时间秒杀一切 提交于 2019-12-02 03:34:58
GIL全局解释器锁: python解释器: 1.Cpython C , 2.Jpython java , 3.Ppython Python GIL全局解释器锁: 基于Cpython来研究全局解释器锁。 1.GIL本质上是一个互斥锁。 2.GIL的为了阻止当前进程内执行多个线程。 ​ 单个进程下的多个线程无法实现并发,但能实现并发 3.这把锁主要是因为CPython的内存管理不是'线程安全'的。 ​ 内存管理 ​ 垃圾回收机制 GIL的存在就是为了保证线程安全的。 注意: 多个线程过来执行,一旦遇到IO操作,就会立马释放GIL解释器锁,交给下一个先进来的线程. 代码演示 import time from threading import Thread, current_thread number = 100 def task(): global number number2 = number # time.sleep(1) number = number2 - 1 print(number, current_thread().name) for line in range(100): t = Thread(target=task) t.start() # 99 Thread-1 98 Thread-2 . . . 1 Thread-99 0 Thread-100 多线程的作用:

Python3 并发编程3

爷,独闯天下 提交于 2019-12-02 03:32:49
目录 GIL全局解释器锁 基本概念 多线程的作用 死锁现象 递归锁 信号量 线程队列 GIL全局解释器锁 基本概念 global interpreter lock 全局解释器锁 GIL不是Python的特性, 是Cpython解释器的特性 GIL本质是一个互斥锁 原因 : Cpython解释器的内存管理不是线程安全的 作用 : 保证同一时间一个线程内只有一个线程在执行 多线程的作用 计算密集型---多进程, GIL原因, 一个进程内的线程只能并发, 不能并行 I/O密集型---多线程, 开启线程与切换线程的速度要快于进程 # 计算密集型 import time import os from multiprocessing import Process from threading import Thread # 计算密集型 def task1(): number = 0 for i in range(100000000): number += 1 print('done!') if __name__ == '__main__': start_time = time.time() lis = [] for i in range(4): # p = Process(target=task1) # 程序执行时间为16.711955785751343 t = Thread(target

day_30

心不动则不痛 提交于 2019-12-02 03:25:56
昨日回顾 进程互斥锁 让并发变成串行,牺牲了效率,保证数据安全. mutex = Lock() 加锁 mutex.acquire() 释放锁 mutex.release() 队列 相当于在内存中开启了一个空间,可以存放一堆数据,这堆数据都得遵循"先进先出". 管道(阻塞) + 锁 q = Queue() 添加数据 q.put(1) 若队列满了,会原地等待 q.put(2) 若队列满了,不会等待直接报错 q.put_nowait(2) 获取数据,遵循先进先出 若队列中没数据,会原地等待 q.get() # 1 若队列中没数据,会直接报错 q.get_nowait() # 1 q.empty() # 判断队列是否为空 q.full() # 判断队列是否满了 IPC进程间通信 通过队列让进程间实现通信 生产者与消费者 生产者:生产数据的 消费者:使用数据的 目的是为了解决供需不平衡的问题 线程 1.什么是线程? 进程: 资源单位 线程: 执行单位 注意: 只要开启一个进程就会有一个线程(主线程). 主线程会在进程结束时,一并销毁. 2.为什么要使用线程? 节省内存资源 开启进程: 1) 开辟一个新的内存空间 2) 会自带一个主线程 开启线程: 1) 一个进程内可以开启多个线程 2) 开启线程的资源远小于进程 GIL全局解释锁 python解释器 Cpython(C语言编写)

10.23GIL全局解释器锁,多线程作用,死锁,递归锁,信号量

蹲街弑〆低调 提交于 2019-12-02 03:20:19
python解释器 cpython C写的 ppython python写的 jpython java写的 GIL全局解释器锁 基于Cpython来研究全局解释器锁 GIL本质上是一个互斥锁 GIL为了阻止同一个进程内多个线程同时执行一个代码 单个进程下的多个线程无法实现并行,但能时间并发 主要是因为cpython的内存管理不是保证线程安全的 内存管理 垃圾回收机制 GIL的存在是为了保证线程安全的 注意:多个线程过来执行,一旦遇到IO操作,就会立马释放GIL解释器锁,交给下一个先进去的线程 多线程的作用 4个任务,每个任务10秒 计算密集型 单核 开启进程: 消耗资源大 4个进程:是40秒 开启线程: 消耗资源院校以进程 4个线程:是40秒 多核 开启进程: 并行,执行效率高 4个进程:是10秒 开启线程: 执行效率低 4个线程:是40秒 IO密集型 单核 开启进程: 消耗资源大 4个进程:是40秒 开启线程: 消耗资源院校以进程 4个线程:是40秒 多核 开启进程: 并行,执行效率低于多线程,因为遇见IO会立马切换CPU的执行权限 4个进程:是40秒+额外开启进程消耗的时间 开启线程: 并发执行,执行效率高于多进程 4个线程:是40秒 在计算密集型的情况下 使用多进程 IO密集型的情况下 使用多线程 高效执行,多个进程内有多个IO密集型的程序 使用多进程+多线程 死锁现象

day30work

こ雲淡風輕ζ 提交于 2019-12-02 03:19:48
GIl全局解释器锁 Python代码的执行由Python虚拟机(也叫解释器主循环)来控制。Python在设计之初就考虑到要在主循环中,同时只有一个线程在执行。虽然 Python 解释器中可以“运行”多个线程,但在任意时刻只有一个线程在解释器中运行。 对Python虚拟机的访问由全局解释器锁(GIL)来控制,正是这个锁能保证同一时刻只有一个线程在运行。 在多线程环境中,Python 虚拟机按以下方式执行: 设置 GIL; 切换到一个线程去运行; 运行指定数量的字节码指令或者线程主动让出控制(可以调用 time.sleep(0)); 把线程设置为睡眠状态; 解锁 GIL; 再次重复以上所有步骤。 GIL本质上是一个互斥锁,目的是为了为了阻止同一个进程内多个线程同时执行(并行)(单个进程下的多个线程无法实现并行,但能实现并发),这把锁主要是因为CPython的内存管理不是 "线程安全" 的,GIL的存在就是为了保证线程安全的,多个线程过来执行,一旦遇到IO操作,就会立马释放GIL解释器锁,交给下一个先进来的线程 import time from threading import Thread, current_thread number = 100 def task(): global number number2 = number time.sleep(2) number =

day30总结

随声附和 提交于 2019-12-02 03:15:40
目录 回顾 TCP服务端实现并发 GIL全局解释器锁 验证多线程的作用 死锁现象 递归锁 信号量 线程队列 回顾 1.进程互斥锁 让并发变成串行,牺牲了效率,保证数据安全. mutex = Lock() # 加锁 ​ mutex.acquire() # 释放锁 ​ mutex.release() 2.队列: 相当于在内存中开启了一个空间,可以存放一堆数据,这堆数据都得遵循"先进先出". 管道(阻塞) + 锁 q = Queue() # 添加数据 ​ q.put(1) # 若队列满了,会原地等待 ​ q.put(2) # 若队列满了,不会等待直接报错 ​ q.put_nowait(2) 获取数据,遵循先进先出 若队列中没数据,会原地等待 q.get() # 1 若队列中没数据,会直接报错 q.get_nowait() # 1 q.empty() # 判断队列是否为空 q.full() # 判断队列是否满了 3.IPC进程间通信 通过队列让进程间实现通信. 4.生产者与消费者 生产者: 生产数据的 消费者; 使用数据的 目的: 解决供需不平衡问题. 通过队列来实现,生产者消费者供需不平衡问题. 5.线程 1.什么是线程? 进程: 资源单位 线程: 执行单位 注意: 只要开启一个进程就会有一个线程(主线程). 主线程会在进程结束时,一并销毁. 2.为什么要使用线程? 节省内存资源

day39

邮差的信 提交于 2019-12-02 03:15:33
目录 python解释器 Cpython Jpython Ppython GIL全局解释器锁 多线程的作用 四个任务,计算密集型,每个任务需要10s: 单核: 多核: 四个任务,IO密集型,每个任务需要10s: 单核: 多核: 总结: 死锁现象(了解) 递归锁(了解) 信号量(了解) 互斥锁: 信号量: 线程队列 python解释器 Cpython 基于C语言 Jpython 基于java Ppython 基于Python GIL全局解释器锁 基于Cpython来研究全局解释器锁。 1.GIL本质上是一个互斥锁。 2.GIL的为了阻止同一个进程内多个线程同时执行(并发) 单个进程下的多个线程无法实现并行,但能实现并发 3.这把锁主要是因为Cpython的内存管理不是“线程安全”的。 ​ 内存管理 ​ 垃圾回收机制 GIL的存在就是为了 保证线程安全的 注意:多个线程过来执行,一旦遇到IO操作,就会立马释放GIL解释器锁,,交给下一个先进来的线程 多线程的作用 四个任务,计算密集型,每个任务需要10s: 单核: 开启进程 消耗资源过大 4个进程:40s 开启线程 消耗资源远小于进程 4个线程:40s 多核: 开启进程 并行执行,效率比较高 4个进程:10s 开启线程 并发执行,执行效率低 4个线程:40s 四个任务,IO密集型,每个任务需要10s: 单核: 开启进程 消耗资源过大