1>先看下基于线程并发的套接字通信
sever端开启一个进程来建立连接,每次有客户接入,就新增一个线程来负责交互
2>很明显的一个问题,每次有客户端接入,服务端都要开启一个线程/进程 去跟客户端建立通信,
进程数或线程数会随着并发客户端的增多而增多,这样终会有服务器资源耗尽的风险,所以,
需要对进程数或线程数加以限制,把数量控制在一个服务器能正常运行所承载的范围内,这就
要进入进程池/线程池来解决这个问题,进程池/线程池本质上也是基于多进程/多线程,只是
加上了数量的限制。
concurrent.futures模块提供了高度封装的异步调用接口
ThreadPoolExecutor:线程池,提供异步调用
ProcessPoolExecutor: 进程池,提供异步调用
进/线程池的方法
submit(fn, *args, **kwargs) : 异步提交任务
map(func, *iterables, timeout=None, chunksize=1) :取代for循环submit的操作
shutdown(wait=True): 相当于进程池的pool.close()+pool.join()操作
wait=True,等待池内所有任务执行完毕回收完资源后才继续
wait=False,立即返回,并不会等待池内的任务执行完毕
但不管wait参数为何值,整个程序都会等到所有任务执行完毕
submit和map必须在shutdown之前
result(timeout=None): 取得结果
add_done_callback(fn): 回调函数
2.1>多进程
2.2>多线程
3>基于线程池的套接字通信
4>map方法
5>回调函数
可以为进程池或线程池内的每个进程或线程绑定一个函数,该函数在进程或线程的任务执行完毕后自动触发,
并接收任务的返回值当作参数,该函数称为回调函数
5.1>先引入一个同步调用机制
如下例子,有一个跑步的函数,有一个计算步数的函数,我想实现多个人跑步,跑完就计算下步数的需求
同步调用的写法如下,submit任务之后,直接调计算的函数计算,
很明显,这样执行效率太低了,我们能否实现,只要一来人就开始跑,跑完就自己计算下步数,而不是上面那种
‘一个一个’执行的情况? 这时候就需要引入异步调用了,add_done_callback(fn),回调函数就是在一个函数
执行完,把函数的返回值当做参数开始执行另外一个函数,改写例子如下