IO 分磁盘IO和网络IO,这里的IO指的是网络IO.

计算机在传输数据的时候 采用的是流传输,如果从系统层看对于一台只有一个网卡的计算机网络IO只有一个.

前面我们在用到socket的时候 用到的send和recv就是在一条IO通道里传输数据的.(先不要考虑多进程和多线程)

通常这种操作是无法完全利用IO的,也就是说 我们没有完全有限的把资源利用起来,就好像

A和B两个地点,两者之间有一条路,在一个时间段内 只有一辆车在行走,

此时IO多路复用就出现了.即 通过一种机制监视多个描述符,一旦某个描述符有变化,就通知相应的程序进行处理.

IO多路复用机制常见的有select poll epoll,还有一个kqueue

三者的区别:

select

  1. 几乎支持所有的平台,

  2. 单个进程监视的文件描述符有数量限制,

  3. 维护大量的文件描述符组成的数据结构的时候,文件描述符越多,复制的开销就越大

  4. 在扫描的时候使用线性扫描,

  5. 需要不断轮询自己的文件描述符集合,知道设备就绪


poll -- 本质与select无区别

  1. 没有最大连接数限制


epoll  -- linux2.6之后出现,是对select和poll的改进

  1. epoll 在把文件描述符从用户态复制到内核态时,只需要一次

  2. 没有最大文件描述符数量限制,

  3. 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