协程

---恢复内容开始---

线程的其他方法

  获取线程名 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任务
Greenlet模块版协程

  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()
gevent版协程
from gevent import monkey;monkey.patch_all()   #识别所有IO
gevent只能识别自已的gevent.sleep()为io,monkey可以把别的io都视为己出

---恢复内容结束---

原文地址:https://www.cnblogs.com/shachengcc1/p/11415145.html