博客整理day31

pythonday31

Event事件

Event事件的作用:

​ 用来控制线程的执行

​ 由一些线程去控制另一些线程

from threading import Event
from threading import Thread
import time

#调用Event类实例化一个对象
e = Event()

#若该方法出现在任务中,则False阻塞  #e.wait()   #False
#若该方法出现在任务中,则将其他线程的False改为True,进入就绪态与运行态  e.set()  #True

def light():
    print('红灯...')
    time.sleep(1)
    #应该开始发送信号,告诉其他线程准备执行
    e.set()    #将car中的False ---> True
    print('绿灯...')
    
def car(name):
    print('等红灯...')
    #让所有汽车进入阻塞
    e.wait()   #False
    print(f'{name}启动...')
    
#让一个light线程任务控制多个car线程任务
t = Thread(target = light)
t.start()

for line in range(10):
    t = Thread(target=car,args=(f'CART{line}'))
    t.start()

线程池与进程池

什么是进程池与线程池

​ 进程池与线程池是用来控制当前程序允许创建(进程/线程)的数量

进程池与线程池的作用

保证在硬件允许的范围内创建(进程/线程)的数量

代码实现

from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
import time

#ProcessPoolExecutor(5)  #5代表只能开启5个进程,不填写,默认以CPU的个数限制进程数
pool = ThreadPoolExecutor(5)  #代表5个线程,不填写,默认以CPU个数*5限制线程数

def task():
    print('任务开始...')
    time.sleep(1)
    print('任务结束...')
   
for line in range(5):
    pool.submit(task)

回调函数

from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
import time

def task(res):
    print('任务开始...')
    time.sleep(1)
    print('任务结束...')
    return 123

# 回调函数
def call_back(res):
    print(type(res))
    res2 = res.result()
    print(res2)

for line in range(5):
    pool.submit(task, 1).add_done_callback(call_back)

协程

协程的作用

进程:资源单位

线程:执行单位

协程:在单线程下实现并发

attention : 协程不是操作系统资源,它是程序起的名字,为了让单线程能实现并发

协程的目的

操作系统:

​ 操作系统下,线程具有多道技术,切换以及保存线程状态

	1. 遇到IO事件
	2. 当占用CPU执行时间过长

协程:

​ 通过手动模拟操作系统的'多道技术',实现切换+保存状态

​ 手动实现遇到IO切换

​ 单线程遇到IO,切换+保存状态

​ 单线程计算密集型,来回切换+保存状态效率反而会降低

优点:

​ 在IO密集的情况下,会提高效率

缺点:

​ 若在计算密集的情况下来回切换,效率反而会降低

协程的使用

yield : yiled可以保存状态,yield的状态保存与操作系统的保存线程状态很像,

​ 但是yield是代码级别控制的,更轻量级

并发: 切换

#串行执行
import time
def consumer(res):
    '''任务1:接收数据,处理数据'''
    pass

def producer():
    '''任务2:生产数据'''
    res=[]
    for i in range(10000000):
        res.append(i)
    return res

start=time.time()
#串行执行
res=producer()
consumer(res) #写成consumer(producer())会降低执行效率
stop=time.time()
print(stop-start) #1.5536692142486572



#基于yield并发执行
import time
def consumer():
    '''任务1:接收数据,处理数据'''
    while True:
        x=yield

def producer():
    '''任务2:生产数据'''
    g=consumer()
    next(g)
    for i in range(10000000):
        g.send(i)

start=time.time()
#基于yield保存状态,实现两个任务直接来回切换,即并发的效果
#PS:如果每个任务中都加上打印,那么明显地看到两个任务的打印是你一次我一次,即并发执行的.
producer()

stop=time.time()
print(stop-start) 
posted @ 2019-10-27 16:44  simple123  阅读(106)  评论(0编辑  收藏  举报