day33 GIL锁 线程队列 线程池
1. 全局解释器锁GIL
Python代码的执行由Python虚拟机(也叫解释器主循环)来控制。Python在设计之初就考虑到要在主循环中,同时只有一个线程在执行。虽然 Python 解释器中可以“运行”多个线程,但在任意时刻只有一个线程在解释器中运行。
对Python虚拟机的访问由全局解释器锁(GIL)来控制,正是这个锁能保证同一时刻只有一个线程在运行。
在多线程环境中,Python 虚拟机按以下方式执行:
a、设置 GIL;
b、切换到一个线程去运行;
c、运行指定数量的字节码指令或者线程主动让出控制(可以调用 time.sleep(0));
d、把线程设置为睡眠状态;
e、解锁 GIL;
d、再次重复以上所有步骤。
在调用外部代码(如 C/C++扩展函数)的时候,GIL将会被锁定,直到这个函数结束为止(由于在这期间没有Python的字节码被运行,所以不会做线程切换)编写扩展的程序员可以主动解锁GIL。
2. 线程队列
queue队列 :使用import queue,用法与进程Queue一样
queue is especially useful in threaded programming when information must be exchanged safely between multiple threads.
- class
queue.
Queue
(maxsize=0) #先进先出
import queue
#先进先出型
q=queue.Queue(3)
q.put(3)
q.put(2)
q.put(1) print(q.get())
print(q.get())
print(q.get()) """
结果
3
2
1
"""
先进先出型
class queue.
LifoQueue
(maxsize=0) #last in fisrt out
import queue q=queue.LifoQueue()
q.put(1)
q.put(2)
q.put(3) print(q.get())
print(q.get())
print(q.get())
"""
结果
3
2
1 """
先进后出行
class queue.
PriorityQueue
(maxsize=0) #存储数据时可设置优先级的队列
import queue q=queue.PriorityQueue()
#put进入一个元组,元组的第一个元素一般是优先级(一般是数字,也可以是非数字),数字越小,优先级越小
q.put((-1,"a"))
q.put((0,"b"))
q.put((10,"c"))
q.put((20,"d")) print(q.get())
print(q.get())
print(q.get())
print(q.get()) """
结果
数字越小,优先级越高,越优先输出
(-1, 'a')
(0, 'b')
(10, 'c')
(20, 'd') """
优先级队列
注:优先级相同的会根据第二元素比较,第二个元素是根据编码的顺序比较,并且第二个元素的类型必须一致并且,是有序的才可以比较
如果两个值的优先级一样,那么按照后面的值的acsii码顺序来排序,如果字符串第一个数元素相同,比较第二个元素的acsii码顺序
TypeError: unorderable types: dict() < dict() 不能是字典
优先级相同的两个数据,他们后面的值必须是相同的数据类型才能比较,可以是元祖,也是通过元素的ascii码顺序来排序
3. Python标准模块--concurrent.futures
#1 介绍
concurrent.futures模块提供了高度封装的异步调用接口
ThreadPoolExecutor:线程池,提供异步调用
ProcessPoolExecutor: 进程池,提供异步调用
Both implement the same interface, which is defined by the abstract Executor class. #2 基本方法
#submit(fn, *args, **kwargs)
异步提交任务 #map(func, *iterables, timeout=None, chunksize=1)
取代for循环submit的操作 #shutdown(wait=True)
相当于进程池的pool.close()+pool.join()操作
wait=True,等待池内所有任务执行完毕回收完资源后才继续
wait=False,立即返回,并不会等待池内的任务执行完毕
但不管wait参数为何值,整个程序都会等到所有任务执行完毕
submit和map必须在shutdown之前 #result(timeout=None)
取得结果 #add_done_callback(fn)
回调函数
import time,random
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor def func(n):
time.sleep(random.randint(1,3))
return n*n if __name__ == '__main__':
p=ProcessPoolExecutor(max_workers=4)
list=[]
for i in range(10):
ret=p.submit(func,i)
list.append(ret)
print(ret.result())
p.shutdown()
for ret in list:
print(ret.result())
from concurrent.futures import ThreadPoolExecutor def func(n):
return n**2 if __name__ == '__main__':
t_p=ThreadPoolExecutor(max_workers=4)
list=[]
for i in range(10):
ret=t_p.submit(func,i)#异步提交任务
list.append(ret)
# print(ret.result()) #等待任务提交之后拿去结果,拿不到就柱塞,拿到了就继续 t_p.shutdown()
print("主进程结束")
for ret in list:
print(ret.result())
ThreadPoolExecutor
from concurrent.futures import ThreadPoolExecutor def func(n):
return n*n
if __name__ == '__main__':
t_p=ThreadPoolExecutor(max_workers=4) # for i in range(10):
# t_p.submit(func,i)
t_p.map(func,range(10)) #map取代了for+submit
map的用法
from concurrent.futures import ThreadPoolExecutor def get(n):
return n*n
def call(m):
print(">>",m)
print(m.result()) if __name__ == '__main__':
t_p=ThreadPoolExecutor(max_workers=4) for i in range(3):
t_p.submit(get,i).add_done_callback(call) """
结果
>> <Future at 0x294c1d0 state=finished returned int> #必须.result才能拿到结果
0
>> <Future at 0x294c1d0 state=finished returned int>
1
>> <Future at 0x294c1d0 state=finished returned int>
4
"""
day33 GIL锁 线程队列 线程池的更多相关文章
- python并发编程之线程剩余内容(线程队列,线程池)及协程
1. 线程的其他方法 import threading import time from threading import Thread,current_thread def f1(n): time. ...
- day34 GIL锁 线程队列 线程池
一.Gil锁(Global Interpreter Lock) python全局解释器锁,有了这个锁的存在,python解释器在同一时间内只能让一个进程中的一个线程去执行,这样python的多线程就无 ...
- Python 线程----线程方法,线程事件,线程队列,线程池,GIL锁,协程,Greenlet
主要内容: 线程的一些其他方法 线程事件 线程队列 线程池 GIL锁 协程 Greenlet Gevent 一. 线程(threading)的一些其他方法 from threading import ...
- GIL锁和进程/线程池
GIL锁 1.GIL锁 全局解释器锁,就是一个把互斥锁,将并发变成串行,同一时刻只能有一个线程使用共享资源,牺牲效率,保证数据安全,也让程序员避免自己一个个加锁,减轻开发负担 带来的问题 感觉单核处理 ...
- python全栈开发 * 线程队列 线程池 协程 * 180731
一.线程队列 队列:1.Queue 先进先出 自带锁 数据安全 from queue import Queue from multiprocessing import Queue (IPC队列)2.L ...
- day 34 线程队列 线程池 协程 Greenlet \Gevent 模块
1 线程的其他方法 threading.current_thread().getName() 查询当前线程对象的名字 threading.current_thread().ident ...
- day35:线程队列&进程池和线程池&回调函数&协程
目录 1.线程队列 2.进程池和线程池 3.回调函数 4.协程:线程的具体实现 5.利用协程爬取数据 线程队列 1.线程队列的基本方法 put 存 get 取 put_nowait 存,超出了队列长度 ...
- Day9 进程同步锁 进程队列 进程池 生产消费模型 进程池 paramike模块
进程同步锁: 当运行程序的时候,有可能你的程序同时开多个进程,开进程的时候会将多个执行结果打印出来,这样的话打印的信息都是错乱的,怎么保证打印信息是有序的呢? 其实也就是相当于让进程独享资源. fro ...
- GIL全局解释器锁、死锁、递归锁、线程队列
目录 GIL全局解释锁 多线程的作用 测试计算密集型 IO密集型 死锁现象 递归锁 信号量(了解) 线程队列 GIL全局解释锁 GIL本质上是一个互斥锁. GIL是为了阻止同一个进程内多个进程同时执行 ...
随机推荐
- sql如何选取两个数据表中的值
一.直接在要选择的数据前面加上数据表的名字就行了 SELECT po.OrderID, p.LastName, p.FirstName FROM Persons AS p, Product_Order ...
- Java-马士兵设计模式学习笔记-迭代器模式-模仿Collectin ArrayList LinckedList
Java Iterator模式 Java Iterator模式, 模仿Collectin ArrayList LinckedList 一.有如下几个类 1.接口Collection.java 2.接口 ...
- Java-马士兵设计模式学习笔记-装饰者模式
Java装饰者模式简介 一.假设有一个Worker接口,它有一个doSomething方法,Plumber和Carpenter都实现了Worker接口,代码及关系如下: 1.Worker.java p ...
- c++ 拷贝构造函数 继承
拷贝构造函数要求把所有变量都需要做拷贝.在有继承关系情况先,子类的拷贝构造函数,需要调用父类拷贝构造函数.示例代码如下: class Base{ public: virtual ~Base(); Ba ...
- EZOJ #87
传送门 分析 由于我不知道壶里到底有多少水,那么显然我第一次 分别向两个杯子分别到 L/2 +1 和 L/2 才是最优的.(这样既维护了两个人的差值不超1,又正好倒了L的水).那么接下来如果壶里还有水 ...
- netty中的PlatformDependent
通过类名就知道这是一个平台有关的类,通过对该类的学习可以帮助我们实现一个跨平台的应用.但是有些方法放的实现不是很好,比如:isWindows0.通过File的separator就可以判断出来.没必要那 ...
- C++面试笔记--STL模板与容器
1.C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构操作.vec ...
- RGB565的转换
RGB色彩模式也就是“红绿蓝”模式是一种颜色标准,是通过对红(R).绿(G).蓝(B)三种颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红.绿.蓝三个通道的颜色,这个标准几 ...
- [OpenGL]点阵显示生日快乐小程序
刚工作没多久的时候,业余学习了OGL的知识(这是写不好的借口吧), 在某个异性生日的时候写了这个程序. 编译平台: MinGW GCC gcc -o happOK happyOK.c -lglut32 ...
- fiddler扩展模拟弱网络环境设置
今天在qq群中有人问到怎么模拟app弱网络环境,我查了下资料,记得之前做测试的时候是设置fiddler断点,app请求后止于fiddler断点,app一直拿不到响应结果就应该要给出网络请求失败的提示, ...