进程池与线程池
进程池:
提前开设了固定个数的进程 之后反复调用这些进程完成工作(后续不再开设新的)
线程池:
提前开设了固定个数的线程 之后反复调用这些线程完成工作(后续不再开设新的)
创建进程池与线程池:
在windows电脑中如果是进程池的使用也需要在__main__下面
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor import time import os # 创建进程池与线程池 # pool = ThreadPoolExecutor(5) # 可以自定义线程数 也可以采用默认策略 pool = ProcessPoolExecutor(5) # 可以自定义线程数 也可以采用默认策略 # 定义一个任务 def task(n): print(n, os.getpid()) time.sleep(2) return '>>>:%s' % n ** 2 # 定义一个回调函数:异步提交完之后有结果自动调用该函数 def call_back(a): print('异步回调函数:%s' % a.result()) # 朝线程池中提交任务 # obj_list = [] for i in range(20): res = pool.submit(task, i).add_done_callback(call_back) # 异步提交 # obj_list.append(res) """ 同步:提交完任务之后原地等待任务的返回结果 期间不做任何事 异步:提交完任务之后不愿地等待任务的返回结果 结果由异步回调机制自动反馈 """ # 等待线程池中所有的任务执行完毕之后 再获取各自任务的结果 # pool.shutdown() # for i in obj_list: # print(i.result()) # 获取任务的执行结果 同步
IO模型
常用的四种IO模型
阻塞IO:最为常见的一种IO模型 有两个等待的阶段(wait for data、copy data)
非阻塞IO: 系统调用阶段变为了非阻塞(轮训) 有一个等待的阶段(copy data) 轮询的阶段是比较消耗资源的
多路复用IO:利用select或者epoll来监管多个程序 一旦某个程序需要的数据存在于内存中了 那么立刻通知该程序去取即可
异步IO:只需要发起一次系统调用 之后无需频繁发送 有结果并准备好之后会通过异步回调机制反馈给调用者
协程
协程介绍:
协程就是在单线程下实现并发,通过代码的方式来欺骗CPU跳过IO操作,尽可能的使CPU持续被占用。
协程实现TCP服务端并发的效果
# 并发效果:一个服务端可以同时服务多个客户端 import socket from gevent import monkey;monkey.patch_all() from gevent import spawn def talk(sock): while True: try: data = sock.recv(1024) if len(data) == 0:break print(data) sock.send(data+b'hello baby!') except ConnectionResetError as e: print(e) sock.close() break def servers(): server = socket.socket() server.bind(('127.0.0.1',8080)) server.listen() while True: sock, addr = server.accept() spawn(talk,sock) g1 = spawn(servers) g1.join() # 客户端开设几百个线程发消息即可