python中select模块_python中的select模块

1、select模块介绍

Python中的select模块专注于I/O多路复用,select方法用来监听文件描述符(fd),当没有文件描述符时间发生时,进程被阻塞;当一个或多个描述符实际发生时,进程被唤醒。

当我们调用select()时:

1、上下文切换转换为内核态

2、将fd从用户空间复制到内核空间

3、内核遍历所有fd,查看其对应事件是否发生

4、如果没发生,将进程阻塞,当设备驱动产生中断或者timeout时间后,将进程唤醒,再次进行遍历

5、返回遍历后的fd

6、将fd从内核空间复制到用户空间

select模块以列表形式接受四个参数,分别是需要监听的可读文件对象,可写文件对象,产生异常的文件对象和超时设置,当某个文件描述符状态改变后,会返回三个列表。

具体实现:

fd_rlist,fd_wlist,fd_elist=select.select(rlist, wlist, xlist, [timeout]))

参数: 可接受四个参数(前三个必须)

rlist: wait until ready for reading

wlist: wait until ready for writing

xlist: wait for an “exceptional condition”

timeout: 超时时间

返回值:三个列表:

1、当参数1 序列中的fd满足“可读”条件时,则获取发生变化的fd并添加到fd_rlist中

2、当参数2 序列中含有fd时,则将该序列中所有的fd添加到 fd_wlist中

3、当参数3 序列中的fd发生错误时,则将该发生错误的fd添加到 fd_elist中

4、当超时时间为空,则select会一直阻塞,直到监听的句柄发生变化

当超时时间 = n(正整数)时,那么如果监听的句柄均无任何变化,则select会阻塞n秒,之后返回三个空列表,如果监听的句柄有变化,则直接执行。

2、select模块实现并发的服务端:

服务端:

importsocketimportselect

s=socket.socket()

s.bind('127.0.0.1','8080')

s.listen(5)

r_list=[s,]

num=0whileTrue:

r1,w1,error=select.select(r_list,[],[],5)

num+=1

print('count is %s'%num)print('r1's length is %s'%len(r1))

for fd inr1:if fd==s:

conn,addr=fd.accept()

r_list.append(conn)

msg=conn.recv(200)

conn.sendall(('first----%s'%conn.fileno()).encode())else:try:

msg=fd.recv(200)

fd.sendall('second'.encode())exceptConnectionAbortedError:

r_list.remove(fd)

s.close()

客户端

importsocket

flag=1s=socket.socket()

s.connect('127.0.0.1','8080')whileflag:

input_msg=input('请输入:')if input_msg=='0':breaks.sendall(input_msg.encode())

msg=s.recv(1024)print(msg.decode())

s.close()

在服务端我们可以看到,我们需要不停的调用select, 这就意味着:

1  当文件描述符过多时,文件描述符在用户空间与内核空间进行copy会很费时

2  当文件描述符过多时,内核对文件描述符的遍历也很浪费时间

3  select最大仅仅支持1024个文件描述符

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值