I/O(input/output),即输入/输出端口。每个设备都会有一个专用的I/O地址,用来处理自己的输入输出信息首先什么是I/O:I/O分为磁盘io和网络io,这里说的是网络io
IO多路复用:
I/O多路复用指:通过一种机制,可以监视多个描述符(socket),一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。
Linux
Linux中的 select,poll,epoll 都是IO多路复用的机制。
Linux下网络I/O使用socket套接字来通信,普通I/O模型只能监听一个socket,而I/O多路复用可同时监听多个socket.
I/O多路复用避免阻塞在io上,原本为多进程或多线程来接收多个连接的消息变为单进程或单线程保存多个socket的状态后轮询处理。
Python
Python中有一个select模块,其中提供了:select、poll、epoll三个方法,分别调用系统的 select,poll,epoll 从而实现IO多路复用。
对于select模块操作的方法:
句柄列表11, 句柄列表22, 句柄列表33 = select.select(句柄序列1, 句柄序列2, 句柄序列3, 超时时间)
参数: 可接受四个参数(前三个必须)
返回值:三个列表
select方法用来监视文件句柄,如果句柄发生变化,则获取该句柄。
- 当 参数1 序列中的句柄发生可读时(accetp和read),则获取发生变化的句柄并添加到 返回值1 序列中
- 当 参数2 序列中含有句柄时,则将该序列中所有的句柄添加到 返回值2 序列中
- 当 参数3 序列中的句柄发生错误时,则将该发生错误的句柄添加到 返回值3 序列中
- 当 超时时间 未设置,则select会一直阻塞,直到监听的句柄发生变化
- 当 超时时间 = 1时,那么如果监听的句柄均无任何变化,则select会阻塞 1 秒,之后返回三个空列表,如果监听的句柄有变化,则直接执行。
利用select监听终端操作实例:
import socket
import select
sk1 = socket.socket()
sk1.bind(("127.0.0.1",8001))
sk1.listen()
sk2 = socket.socket()
sk2.bind(("127.0.0.1",8002))
sk2.listen()
sk3 = socket.socket()
sk3.bind(("127.0.0.1",8003))
sk3.listen()
li = [sk1,sk2,sk3]
while True:
r_list,w_list,e_list = select.select(li,[],[],1) # r_list可变化的
for line in r_list:
conn,address = line.accept()
conn.sendall(bytes("Hello World !",encoding="utf-8"))