前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >select模块(I/O多路复用)

select模块(I/O多路复用)

作者头像
小小咸鱼YwY
发布2019-07-24 16:48:46
5270
发布2019-07-24 16:48:46
举报
文章被收录于专栏:python-爬虫python-爬虫

0709自我总结

select模块

一.介绍

Python中的select模块专注于I/O多路复用,提供了select poll epoll三个方法(其中后两个在Linux中可用,windows仅支持select),另外也提供了kqueue方法(freeBSD系统)

二.select方法

r_list,w_list,e_list = select.select(rlist, wlist, xlist, [timeout])

三个参数

  • rlist
    • wait until ready for reading(等待,直到准备阅读)
    • 在tcp协议中accept与recv都存在一个等待的过程他们要等数据过来才会执行消息发来后他会进入一个可读状态
  • wlist
    • wait until ready for writing(等待,直到准备写)
    • 在tcp协议send不存在一个等待的过程,他会直接把信息丢到缓存,然后这时候会进入可写状态
  • xlist
    • wait for an “exceptional condition”(等待,有异常情况)
  • timeout
    • 当超时时间为空,则select会一直阻塞,直到监听的句柄发生变化
    • 当超时时间 = n(正整数)时,那么如果监听的句柄均无任何变化,则select会阻塞n秒,之后返回三个空列表,如果监听的句柄有变化,则直接执行。

示例:

服务端

代码语言:javascript
复制
import socket
import time
import select
s = socket.socket()
s.bind(("127.0.0.1",1688))
# 设置为非阻塞 模型
s.setblocking(True) #在多路复用中  阻塞与非阻塞没有区别 因为select会阻塞直到有数据到达为止
s.listen(5)
# 待检测是否可读的列表
r_list = [s]
# 待检测是否可写的列表
w_list = []
# 待发送的数据
msgs = {}
print("开始检测了")
while True:
    read_ables, write_ables, _= select.select(r_list,w_list,[])
    print("检测出结果了!")
    # print(read_ables,"可以收数据了")
    # print(write_ables,"可以发数据了")
    # 处理可读 也就是接收数据的
    for obj in read_ables: # 拿出所有可以读数据的socket
        #有可能是服务器 有可能是客户端
        if s == obj: # 服务器
            print("来了一个客户端 要连接")
            client,addr = s.accept()
            r_list.append(client)  # 新的客户端也交给select检测了
        else:# 如果是客户端则执行recv 接收数据
            print("客户端发来一个数据")
            data = obj.recv(1024)
            print("有个客户端说:",data)
            # 将要发送数据的socket加入到列表中让select检测
            w_list.append(obj)
            # 将要发送的数据已经socket对象丢到容器中
            if obj in msgs:  # 由于容器是一个列表 所以需要先判断是否已经存在了列表
                msgs[obj].append(data)
            else:
                msgs[obj] = [data]
    # 处理可写的 也就是send发送数据
    for obj in write_ables:
        msg_list = msgs.get(obj)
        if msg_list:
            # 遍历发送所有数据
            for m in msg_list:
                obj.send(m.upper())
            # 数据从容器中删除
            msgs.pop(obj)

        # 将这个socket从w_list中删除
        w_list.remove(obj)

客户端

代码语言:javascript
复制
import socket
c = socket.socket()
c.connect(("127.0.0.1",1688))

while True:
    msg = input("").strip()
    if not msg:continue
    c.send(msg.encode("utf-8"))
    print(c.recv(1024).decode('utf-8'))

后续几种方法以后总结补充

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-07-09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0709自我总结
  • select模块
    • 一.介绍
      • 二.select方法
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档