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模块实现并发的服务端:

服务端:

import socket
import select
s=socket.socket()
s.bind('127.0.0.1','8080')
s.listen(5)
r_list=[s,]
num=0
while True:
    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 in r1:
        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())
             except ConnectionAbortedError:
                r_list.remove(fd) 
s.close()   

客户端

import socket
flag=1
s=socket.socket()
s.connect('127.0.0.1','8080')
while flag:
    input_msg=input('请输入:')
    if input_msg=='0':
        break
    s.sendall(input_msg.encode())
    msg=s.recv(1024)
    print(msg.decode())
 s.close()

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

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

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

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

转载于:https://www.cnblogs.com/dushangguzhousuoli/p/11005997.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值