day34 GIL锁 线程队列 线程池

一、Gil锁(Global Interpreter Lock)

python全局解释器锁,有了这个锁的存在,python解释器在同一时间内只能让一个进程中的一个线程去执行,这样python的多线程就无法利用多核优势,但是这并不是python语言本身的缺点,是解释器的缺点,这个问题只存在于Cpython解释其中,像Jpython就没有。但是Cpthon是python官方解释器(算目前运行效率最高的吧),所以多数人都以为Gil锁是python语言的弊端。

#GIL锁图解

 

过程解释:

1、加载python解释器代码

2、加载自己的py文件

3、py文件作为参数传给解释器(因为有GIL锁,一次只能一个线程进入)

4、解释器将py文件编译成.pyc字节码文件

5、解释器通过虚拟机将字节码文件转为二进制文件

6、二进制文件等待cpu调用

二、线程队列

import queue

线程队列有三种形式

1、先进先出

q = queue.Queue(3)    创建一个长度为3的队列,先进先出

q.put()   

q.get()

q.size()    #当前队列中有多少个元素

2、后进先出

q = queue.LifoQueue(3)     创建一个长度为3的后进先出队列

3、优先级队列

q = queue.PriorityQueue(3)    创建一个长度为3的优先级队列

 1 import queue
 2 # q = queue.Queue()
 3 # q =queue.LifoQueue()
 4 q = queue.PriorityQueue() #优先级队列
 5 # put里是一个元组,元组的一个元素代表优先级(通常是数字,也可以是非数字,数字越小,优先级越高),第二个元素是存入队列中的值
 6 #一个队列中,优先级必须是同一种数据类型,才能比较,否则会报错
 7 # 如果优先级相同,那么按照后面值的ASCII码的顺序来排序
 8 #优先级相同的数据,他们后面的值必须是相同的数据类型才能比较,但优先级相同的两个字典无法比较
 9 
10 # q.put((-1,'ca'))   #优先级相同的两个字符串,逐个比较ASCII码值
11 # q.put((-1,'cb'))
12 
13 # q.put(("a","d"))    #优先级为非数值类型
14 # q.put(('b',"c"))
15 
16 # q.put((1,{1:'hh',2:'ss'}))   #优先级相同的两个字典,无法比较,报错
17 # q.put((1,{3:'dd',4:'jj'}))
18 
19 q.put((2,(4,5)))    #优先级相同的元组,逐个比较元组元素值
20 q.put((2,(4,4)))
21 
22 print(q.get())
23 print(q.get())
优先级队列详解

三、concurrent.futures模块

通过这个模块可以创建和使用线程池和进程池

格式

from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor

t = ThreadPoolExecutor(max_workers=4)     #创建一个线程池对象,容量为4

方法:

t.submit(fun,*args,*kwargs)              #异步提交任务

res= t.submit(fun,*args,*kwargs)     #返回值是一个对象

res.result()           #从对象中取值,会等待任务的执行结果,等不到是阻塞

t.shutdown)         #等待已提交任务完成,相当于close()和join()的效果

t.map(fun, iter)                #异步提交任务

res = t.map(fun, iter)      #返回结果是一个生成器对象

for el  in  res:              #取值

  print(el) 

add_done_callback(fun2)        #添加回调函数

t.submit(fun1,参数).add_don_callback(fun2)     #调用回调函数语法

原文地址:https://www.cnblogs.com/zhang-yl/p/10060263.html