IO 分磁盘IO和网络IO,这里的IO指的是网络IO.
计算机在传输数据的时候 采用的是流传输,如果从系统层看对于一台只有一个网卡的计算机网络IO只有一个.
前面我们在用到socket的时候 用到的send和recv就是在一条IO通道里传输数据的.(先不要考虑多进程和多线程)
通常这种操作是无法完全利用IO的,也就是说 我们没有完全有限的把资源利用起来,就好像
A和B两个地点,两者之间有一条路,在一个时间段内 只有一辆车在行走,
此时IO多路复用就出现了.即 通过一种机制监视多个描述符,一旦某个描述符有变化,就通知相应的程序进行处理.
IO多路复用机制常见的有select poll epoll,还有一个kqueue
三者的区别:
select几乎支持所有的平台,
单个进程监视的文件描述符有数量限制,
维护大量的文件描述符组成的数据结构的时候,文件描述符越多,复制的开销就越大
在扫描的时候使用线性扫描,
需要不断轮询自己的文件描述符集合,知道设备就绪
poll -- 本质与select无区别没有最大连接数限制
epoll -- linux2.6之后出现,是对select和poll的改进epoll 在把文件描述符从用户态复制到内核态时,只需要一次
没有最大文件描述符数量限制,
epoll为每个文件描述符指定一个回调函数,设备就绪后在等待队列上的等待者的时候就会调用这个函数 (这里的等待列队是epoll内部定义的等待队列)
python中有一个select模块.提供了select\poll\epoll三种方法,分别调用系统中的select\poll\epoll来实现IO多路复用
注意:
在win 和 mac 下 都只支持select
在linux下 select\poll\epoll三种 都支持
select()的参数是三个列表 (必填)select.select(rlist,wlist,xlist,timeout=None)
rlist: 序列中的句柄发生可读时(accetp和read),则获取发生变化的句柄并添加到 返回值1 序列中
wlist: 序列中含有句柄时,则将该序列中所有的句柄添加到 返回值2 序列中
xlist:序列中的句柄发生错误时,则将该发生错误的句柄添加到 返回值3 序列中
例
import select
import threading
import sys
while True:
readable, writeable, error = select.select([sys.stdin,],[],[],1)
if sys.stdin in readable:
print 'select get stdin',sys.stdin.readline()
Queue模块
import Queue
mq = Queue.Queue(maxsize=10)
Queue.Queue类 是队列的一个实现,可指定或者不指定队列长度,maxsize为可选参数,用来设置队列的长度.
常用的方法
put(item, block=True, timeout=None)
向队列中添加一个元素,如果队列已满 则等待.
item参数为必填项,为插入的值,
block为可选参数,默认为True
timeout为可选参数,默认为None
get(block=True,timeout=None)
删除并返回队列中的一个元素,如果队列为空,则等待,
mq.put_nowait()
mq.()
用法同上,但是不等待.
其他用法
qsize() 返回队列的大小
empty() 如果队列为空,返回True,反之False
full() 如果队列满了,返回True,反之False
task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号
join() 实际上意味着等到队列为空,再执行别的操作
参考:
http://www.cnblogs.com/alex3714/p/4372426.html
http://www.cnblogs.com/Anker/p/3265058.html
http://www.cnblogs.com/wupeiqi/articles/5040823.html
个人Blog
www.timesnotes.com