也知道了 epoll
目前 Linux 上效率最高的 IO多路复用 技术 !
那怎么使用 epoll
> IO多路复用选择器
# 实例化一个 epoll 选择器
>>>selector = selectors.DefaultSelector()
# 删除注册事件
>>>selector.unregister(connection)
# 定义一个回调函数
>>>def accept(server):
# 设置成非阻塞
>>>connection.setblocking(False)
# 处理消息的函数注册
>>>selector.register(connection, selectors.EVENT_READ, read)
#把监听套接字和生成对等套接字的函数注册到read事件(有用户连接)
>>>selector.register(server, selectors.EVENT_READ, accept)
# 查询,返回所有已经准备好资源的打包对象
>>>events = selector.select()
# 回掉函数
>>>callback = key.data
# 连接客户端的套接字
>>>sock = key.fileobj
# 不需要关心是什么套接字,什么事件,只需要调用对应的回调函数即可
>>>callback(sock)
基本思路
>先在指定的套接字上注册对应的事件及回调;
>不断的查询所有已经准备好资源的套接字;
>不需要考虑套接字与事件只管调用。
### 阻塞 VS 非阻塞
阻塞IO:
- 在1、2阶段都发生阻塞; - 调用阻塞IO会一直block住进程,直到操作完成
非阻塞IO:
- 在第1阶段没有阻塞,在第2阶段发生阻塞; - 当用户进程发出IO请求时, 如果内核中的数据还没由准备好,那么它并不会block用户进程,而是立即返回一个错误, 在程序看来,它发起一个请求后,并不需要等待,而是马上就得到一个结果。 - 非阻塞IO需要不断轮询,查看数据是否已经准备好了;
阻塞与非阻塞可以简单理解为调用一个IO操作能不能立即得到返回应答,如果不能立即获得返回,需要等待,那就阻塞了;否则就可以理解为非阻塞 。