Event事件
什么是Event事件
Event是python的threading模块中的一个类,它的作用是可以通过一些线程来控制另一些线程。
怎么使用
因为它是一个类,所以首先需要先实例化一个对象,通过对象来调用它的一些方法
wait
该方法可以将线程变为false,即阻塞状态
set
它可以将wait方法改变的线程重新变为就绪和执行
from threading improt Event,Thread
import time
def light():
print('红灯亮了。。')
time.sleep(5)
# 让汽车线程进入运行或就绪状态
e.set()
print('绿灯亮了。。')
def car(name):
print('等待红灯中。。')
# 红灯时让线程进入等待状态
e.wait()
print(f'{name}开始行驶')
# 开启一个灯线程
t = Thread(target=light)
t.start()
# 开启十个汽车线程
for name in range(10):
t = Thread(target=car,args=(f'汽车{name}号',))
t.start()
进程池和线程池
什么时进程池什么是线程池
进程池和线程池是用来控制当前程序允许进程或线程的数量,为了保证在硬件允许的范围内创建进程或线程
如果你创建的线程大于线程池的限制,每结束一个线程,他才会再放入一个线程
进程池和线程池都是python的模块
使用方法
pool = ProcessPoolExecutor(5)
只能开启5个进程,不写默认使用cpu个数限制进程数
pool = ThreadPoolExecutor(5)
不写默认使用cpu个数*5限制线程数
pool.submit('函数地址').add_done_callback('回调函数地址')
当一个函数的返回值可以传给另一个函数当作参数时可以使用回调函数
pool.shutdown()
会让所有线程池的任务结束后,才往下执行代码
from concurrent.futures import ThreadPoolExecutor
import time
pool = ThreadPoolExecutor(5)
def task():
print('线程开始')
time.sleep(1)
print('线程结束')
return 123
def call_back(res):
print(type(res))
# 不要重名
res2 = res.result()
print(res2)
for i in range(10):
pool.submit(task).add_done_callback(call_back)
pool.shutdown()
print('the end')
这里要注意的是
- 在回调函数中,传的值是一个类,需要调用result方法才能得到具体的值
- 赋值操作不要和接收的形参重名,可能在高并发的情况下有可能会出现bug
协程
什么是协程
认识协程之前回顾一下线程和进程
线程是是一个资源单位,线程是执行单位
而协程是基于单线程下实现的并发,就是一个线程同时处理多个任务
怎么实现协程
可以通过第三放模块'gevent
这个模块可以监视IO并切换线程
monkey.patch_all() 可以监听该程序下所有的IO操作
spawn, joinall 用于做切换 + 保存状态
from gevent import monkey
monkey.patch_all() # 可以监听该程序下所有的IO操作
import time
from gevent import spawn, joinall # 用于做切换 + 保存状态
def func1():
print('1')
# IO操作
time.sleep(1)
def func2():
print('2')
time.sleep(3)
def func3():
print('3')
time.sleep(5)
start_time = time.time()
s1 = spawn(func1)
s2 = spawn(func2)
s3 = spawn(func3)
# s2.join() # 发送信号,相当于等待自己 (在单线程的情况下)
# s1.join()
# s3.join()
# 必须传序列类型
joinall([s1, s2, s3])
end_time = time.time()
print(end_time - start_time)