博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IO多路复用
阅读量:5336 次
发布时间:2019-06-15

本文共 2636 字,大约阅读时间需要 8 分钟。

定义:同时监控多个IO事件,当哪个IO事件准备就绪,就执行哪个IO事件,以此形成可用同时操作多个IO的并发行为,避免一个IO阻塞,造成所有的IO都无法执行

IO准备就绪:是一种IO必然要发生的临界状态

具体方案:

select ---> windows linux unix
poll ---> linux unix
epoll ---> linux unix

三种方案都在select模块中

--------------------select------------------------------------

rs, ws, xs = select(rlist, wlist, xlist[, timeout])

功能:监控IO事件,阻塞等待IO事件发生
参数:rlist 列表 存放我们监听等待处理的IO事件
   wlist 列表 存放我们要主动操作的IO事件
     xlist 列表 我们要关注出错处理的IO事件
     timeout 超时时间
返回值:rs 列表 rlist中准备就绪的IO
    ws 列表 wlist中准备就绪的IO
    xs 列表 xlist中准备就绪的IO

注意:

* 在处理IO时不要形成死循环,让一个客户端单独占有服务端
* IO多路复兴形成一种可以同时处理多个IO的效果,效率较高

from select import selectfrom socket import *s = socket()#端口的复用,当服务器关闭时,立马释放端口s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)s.bind(('0.0.0.0',10003))s.listen(5)rlist=[s]wlist=[]xlist=[]while True:    #提交监测我们关注的IO等待IO发生    rs, ws, xs = select(rlist, wlist, xlist)    for r in rs:        if r is s:            c, addr = r.accept()            print("Connect from",addr)            rlist.append(c)   #添加到关注列表        else:            data = r.recv(1024)            if not data:                rlist.remove(r)                r.close()            else:                print(data.decode())                #将客户套接字放入wlist列表                wlist.append(r)    for w in ws:        w.send(b"Receive your message")        wlist.remove(w)    for x in xs:        if x is s:            s.close()

------------------------------poll--------------------------

步骤

1.创建poll对象
  p = select.poll()
2.添加注册事件
  p.register(s)
  也可以移除注册事件
  p.unregister(s)
3.阻塞等待IO发生
  events = p.poll()
  功能:阻塞等待IO发生
  返回值:events是一个列表,列表中每一个元素都是一个元组,代表一个发生的IO事件
  [(fileno, event),(),()......]
  就绪IO的文件描述符 具体就绪的事件
  **需要通过文件描述符(fileno)找到对应的IO对象
4.处理具体的IO

事件类别

  POLLIN     POLLOUT     POLLERR   POLLHUP     POLLPRI
  rlist      wlist      xlist   断开      紧急处理

 

from socket import *from select import *#创建套接字做为我们关注的IOs = socket()s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)s.bind(('0.0.0.0',10003))s.listen(5)#创建poll对象p = poll()#fileno ---> IO对象的字典fdmap = {s.fileno():s}#注册关注的IOp.register(s,POLLIN | POLLERR)while True:    #进行IO监控    events = p.poll()    for fd,event in events:        if fd == s.fileno():            c,addr = fdmap[fd].accept()            print("Connect from", addr)            p.register(c,POLLIN | POLLHUP)            fdmap[c.fileno()] = c        elif event & POLLIN:  #利用事件来进行与运算,来判断是否有这事件            data = fdmap[fd].recv(1024)            if not data:                #客户端退出,从关注事件移除                p.unregister(fd)                fdmap[fd].close()                del fdmap[fd]            else:                print(data.decode())                fdmap[fd].send(b"Receive")

 

转载于:https://www.cnblogs.com/zengsf/p/9607431.html

你可能感兴趣的文章
【BZOJ-2295】我爱你啊 暴力
查看>>
【BZOJ-1055】玩具取名 区间DP
查看>>
Oracle安装配置—64位Win7安装配置64位Oracle
查看>>
Bit Twiddling Hacks
查看>>
个人总结
查看>>
[USACO08MAR]土地征用Land Acquisition
查看>>
Windwos中的线程同步
查看>>
LeetCode : Reverse Vowels of a String
查看>>
时间戳与日期的相互转换
查看>>
获取手机当前经纬度的方法
查看>>
oracle 导出与导入
查看>>
规避字符串在传递过程中造成的编码问题
查看>>
HTTP协议
查看>>
jmeter(五)创建web测试计划
查看>>
使用git pull文件时和本地文件冲突怎么办?
查看>>
python基本数据类型
查看>>
1305: [CQOI2009]dance跳舞 - BZOJ
查看>>
关于TDD的思考
查看>>
Cocos2d-x学习之windows 7 android环境搭建
查看>>
将html代码中的大写标签转换成小写标签
查看>>