Linux下C编程(3)
6) = -1 EAGAIN (Resource temporarily unavailable) read(0, 0x80498c0, 4096) = -1 EAGAIN (Resource temporarily unavailable) --- SIGINT (Interrupt) @ 0 (0) --- killed by SIGINT [windriver@windriver-machine ltest]$ [windriver@windriver-machine ltest]$ cat noread.c #include<stdio.h> #include<unistd.h> #include<fcntl.h> #include<stdlib.h> #include<errno.h> char buffer[4096]; int main(int argc,char** argv) int delay = 1,n,m = 0; while(1) 3)I/O复用,I/O复用的基本想法就是使用一个数据结构来存储I/O操作与FD的映射关系,使用专门的函数select和poll来检测socketFD,一旦FD上数据准备好,则直接就可以使用I/O操作.
3.1)I/O复用之信号驱动方式 这种方式不使用select 函数,只是在应用刚建立时安装好相应的信号,然后在信号处理程序中进行数据I/O操作.这方法一般不建议使用,毕竟信号量是一种比较大的中断操作,会导致系统停顿,内核是否支持这种SIGIO信号量,还有SIGIO是否是SOCKET操作以及I/O操作集中于信号处理程序中.这些都是需要考虑的因素,一般不建议使用.
3.2)I/O复用之异步I/O模式,这只见于POSIX.1的1993版本中,是2.6内核的一个标准特性,简称AIO,基本思想是允许进程发起很多I/O操作,而不用阻塞或者等特操作完成.虽然是2.6标准特性,但复杂,目前没有很好的实现.
3.3)select 函数是建立在fd_set这个数据类型基础之上,本质上对FD集合的枚举过程,它的操作过程非常简单,就是在三种类型的FD集合中,在指定时间范围内检测是否有数据准备好,如果准备好,则返回大于0数值表示,如下图所示,
其中maxfdp1是需要检查的文件描述符个数,通常是后面三种文件描述符集合中FD值最大值加上1.这主要是为了枚举性能考虑,而不是将所有FD都算上.返回值是响应I/O操作的操作文件描述符的数量的最大值,因此,如果有多个FD,需要使用FD_ISSET进行测试是否是当前返回.另外在不同平台的fd_set长度不同,通常系统默认是FD_SET_SIZE是1024,可以通过修改参数,并且内部实现不一样,通常使用一些宏操作进行增删清空. 这里说到select函数,实际上还有一个非常类似的函数是poll,通常poll是System V标准,而select是BSD标准. 但是LINUX比较搞,它是上层用SELECT,实际上底层还是用的POLL. 在LINUX下实际上POLL性能比SELECT要高一点,POLL也是监视FD集合,不过将这个FD集合单独使用一个数据结构pollfd. struct pollfd { 然后用poll(struct pollfd *ufds,unsigned int nfds, int timeout),poll枚举一个确定的FD集合,并且使用确定的事件来关注,通过返回这些确定的事件,可以确定I/O读写.相对于select来说,没有FD_SETSIZE限制.但是仍然需要对FD集合进行线性扫描. [windriver@windriver-machine ltest]$ gcc pollexam.c -o pollexam |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |