---恢复内容开始---
线程的其他方法
获取线程名 current_thread().getname()
获取线程id current_thread().ident()
线程队列(重点)
队列中的数据被多个线程同时取也是只有一个可以拿到
先进先出队列,与进程中队列相同
先进后出队列,q = queue,LifoQueue(3),类似于栈
优先级队列,q = PriorityQueue(3),放入的时候写入元组(5,'aaa') 5为序号,越小的越先取,取的时候显示元组。
如果元组第0项的优先级序号相同,类型不同会报错,相同则比较第二个元素在ascii表中的位置
序号可以为负数,纯数学方法比较大小
线程池(重点)
为了减少创建销毁线程的时间开销
列表的方式提交任务和读取结果可以避免程序执行时的阻塞
1 from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor 2 import time 3 from threading import current_thread 4 5 def f1(n): 6 #print('%s号线程'%current_thread().ident) 7 time.sleep(1) 8 #print(n) 9 return n*n 10 11 if __name__ == '__main__': 12 tp = ThreadPoolExecutor(4) 13 14 #tp.map(f1,range(10))#提交任务的方法一,异步提交任务,但是只能是可迭代对象 15 16 res_list = [] 17 for i in range(10): 18 res = tp.submit(f1,i) #submit异步提交任务 19 res_list.append(res) 20 # 21 # for r in res_list: 22 # print(r.result()) #此时打印是四个四个出数据 23 24 tp.shutdown() #主线程等待所有提交给线程池的任务都执行完,相当于close()加join(),锁住池子且等待 25 26 for r in res_list: 27 print(r.result()) #此时打印是执行完了的数据一起出
进程池与线程池的切换
1 from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor 2 import time 3 from threading import current_thread 4 5 def f1(n): 6 #print('%s号线程'%current_thread().ident) 7 time.sleep(1) 8 #print(n) 9 return n*n 10 11 if __name__ == '__main__': 12 #tp = ThreadPoolExecutor(4) 13 tp = ProcessPoolExecutor(4) #替换这一个语句即可 14 15 #tp.map(f1,range(10))#提交任务的方法一,异步提交任务,但是只能是可迭代对象 16 17 res_list = [] 18 for i in range(10): 19 res = tp.submit(f1,i) #submit异步提交任务 20 res_list.append(res) 21 # 22 # for r in res_list: 23 # print(r.result()) #此时打印是四个四个出数据 24 25 tp.shutdown() #主线程等待所有提交给线程池的任务都执行完,相当于close()加join(),锁住池子且等待 26 27 for r in res_list: 28 print(r.result()) #此时打印是执行完了的数据一起出 29 30 31 32 # # tp = ThreadPoolExecutor(4) 33 # tp = ProcessPoolExecutor(4) # 进程池和线程池的切换,替换这一个语句即可,其他不需改动,完全相同
协程:
提高单线程的效率,在IO时间内执行任务,即一个线程实现并发
使用生成器实现协程
1 import time 2 def f1(): 3 for i in range(10): 4 time.sleep(1) 5 print('f1>>',i) 6 yield 7 8 def f2(): 9 g = f1() 10 for i in range(10): 11 time.sleep(1) 12 print('f2>>',i) 13 next(g) 14 15 #通过生成器实现了并发
Greenlet模块(不能提高效率,具体代码仅供了解)
此时的切换是在已经记录了原有执行进度的基础上进行的,不是从头再来
1 from greenlet import greenlet 2 import time 3 4 def f1(): 5 print('f1') 6 g2.switch() #切换到g2任务去执行 7 time.sleep(1) 8 print('第二次f1') 9 g2.switch() 10 def f2(): 11 print('f2') 12 g1.switch() 13 time.sleep(1) 14 print('第二次f2') 15 g1 = greenlet(f1) #实例化一个greenlet对象 16 g2 = greenlet(f2) 17 18 g1.switch() #执行g1任务
Gevent模块(重点)真正的协程,
1 import gevent 2 3 4 def f1(): 5 print('f1') 6 gevent.sleep(2) 7 print('第二次f1') 8 9 def f2(): 10 print('f2') 11 gevent.sleep(2) 12 print('第二次f2') 13 14 g1 = gevent.spawn(f1) #异步提交两个任务 15 g2 = gevent.spawn(f2) #主进程结束,这两个都结束 16 17 g1.join() 18 g2.join()
from gevent import monkey;monkey.patch_all() #识别所有IO
gevent只能识别自已的gevent.sleep()为io,monkey可以把别的io都视为己出
---恢复内容结束---