开进程和线程都需要消耗资源,只不过相对一两者比较,线程比较少,在计算机的最大层度的利用计算机
什么是池
在保证计算机硬件的安全情况下最大限度的利用计算机
池其实是降低了程序的运行效率,但保证了计算机的安全(硬件的发展,跟不上软件的速度)
from concurrent.futures import ProcessPoolExecutor,HtreadPoolExecutor
pool = ProcessPoolExecutor(5) # 开启进程池
# pool = HtreadPoolExecutor(5) # 开启线程池
def func():
i = 0
for i in range(10):
print("func")
i += 1
return i
def call_back(i):
print(i.result()) # 注,返回的结果必须使用result()
if __name__ == '__main__':
pool.submit(func).add_done_callback(call_back) # 添加任务,使用异步回调,将处理结果的函数放入括号类
# 拿到的值会自动的当做参数传入函数中
注意,开线程池和,进程池是一样的。j将ProcessPoolExecutor换成HtreadPoolExecutor就可以了
协程
我么先来总结一下,进程,线程,再来说协程
进程;资源单位
线程;执行单位
那么协程是生么呢;就是单线程下实现并发,它完全是程序员意淫出来的名词,
说道单线程实现并发,我们就不得不提一下多道技术
时间上的复用
切换加保存状态
空间上的复用
公用计算机上的一套硬件设备
程序员,在代码上通过自己检测程序中的io,一旦遇到io就通过代码切换给操作系统一个假象,认为没有遇见io,从而让程序在运行,和就绪态之间切换,提升程序的运行效率
注意,不是切换加保存状态就会提升效率
我们应该从两个方面来讲
1io密集型
提升效率
2计算密集型
降低效率
可以保存状态,我们先想到了生成器
最后想到了yield
但是yield是不能识别io的,所以我们必须得放弃yield
我们需要找到一个识别io的工具(gevent模块)
from gevent import monkey;monkey.patch_all() # 只要是协程我们就会要用到这句语法,固定格式
from gevent import spawn
import time
def func():
time.sleep(2)
print("func")
def index():
time.sleep(3)
print("index")
if __name__ == '__main__':
s1 = spawn(func) # spawn 这个方法,会将写入的函数名自动调用,
s2 = spawn(index)
s1.join() # 等待,所有的执行的协程结束,主线程才会结束
s2.join()