深入Linux网络编程(二):异步阻塞IO

2014-11-24 09:26:55 · 作者: · 浏览: 1

当从一个描述符读,写到另一个描述符时,可以在下列形式的循环中使用阻塞IO:


这种形式的阻塞IO随处可见,但如果必须从两个描述符读呢?这种方式就可能导致长时间阻塞在其中一个描述符上,而另一个描述符虽然有很多数据却不能及时处理。


一种直观的解决方法是这样的:将两个描述符都设置为非阻塞,对第一个描述符发送read,如果有数据则读取并处理,如果没有则立即返回,对第二个描述符做同样处理。此后等待若干秒,再度去第一个描述符。这种形式的循环称为轮询(polling),缺点非常明显:大部分时间是无数据可读的,但是仍然花费时间反复执行read


异步阻塞IO基于这样一个想法:先构建一张有关描述符的列表,然后使用统一的阻塞函数,当任何socket有事件通知时跳出阻塞状态。



select就是这样一个统一的阻塞函数。


select()可以监视多个文件描述符,直到其中的一个或一些文件描述符的IO操作准备就绪,所谓就绪是指IO操作的请求不会被阻塞。


这个参数表示愿意阻塞等待的时间。


这Sanger参数是指向描述符集的指针,说明了我们关心的可读可写或处于一场条件的各个描述符。这个描述符集使用位图的方式存储每个fd的状态。


这三个参数任意一个或者全部都可以是空指针,表示对相应状态不关心。如果都是空指针,则select提供了比sleep更精确的计时器。


这些宏或者参数负责对描述符集的结构做一些操作:清除、测试、置位、全部清除。


注意一个描述符阻塞与否并不影响select是否阻塞,