您的位置:首页 > 其它

I/O复用

2014-12-09 22:27 134 查看

1. I/O复用概念

I/O复用是指,在进程指定的一个或多个I/O条件就绪时,内核就能通知进程;

《UNIX网络编程》中使用这样一个例子:

大致代码流程如下,client端:

{
socket(...);
........//设置服务器地址、端口号等;
connect(...);
........
str_cli(stdin, sockfd);
}

void str_cli(...)
{
while(fgets()//从标准输入读数据)
{
write();//向服务器发送数据
if(EOF == readline())//从sockfd接收数据;
{
挂掉;
}
}
}


server端:

socket();
bind();
listen();
accept();
之后,从客户端收发数据;


启动客户/服务器对,然后kill掉服务器子进程;

客户端从标准输入读取数据之后,发送给服务器端,并从服务器端接收数据输出;kill掉服务器子进程时,会想client发送FIN报文,client端会回应一个ACK,此时client阻塞在fgets()调用上,暂时看不到这个EOF;此时输入一串字符串,client从fges()返回,并向服务器端发送数据,但是此时服务器端已经挂了,于是服务器端会直接回应一个RST,但是client端再向服务器端发送数据之后就调用了readline()读取服务器发送来的数据,由于前面接收到了服务器端发来的FIN,所以直接返回EOF,客户端就直接挂掉了;

这里client应该阻塞在套接字和标准输入的任何一个上面,而不只是阻塞在标准输入上;

2. 几种I/O模型

一个输入操作一般包括两个阶段:
(1)等待数据准备好;
(2)从内核向进程复制数据;

2.1 阻塞式I/O



默认情况下,所有套接字都是阻塞的;

对于阻塞式I/O而言,输入操作的两个阶段都是被阻塞的;

2.2 非阻塞式I/O

非阻塞式I/O一般采用轮询的方式,不断尝试读取,这种方式比较耗CPU;

2.3 I/O复用模型



select()允许指定等待多个事件,当其中的一个或多个发送或到达超时事件后才唤醒;

2.4 信号驱动式I/O模型

设置SIGIO的信号处理程序,在信号处理程序中调用recvfrom读取数据;

2.5 异步I/O模型

调用aio_xxx开始的函数,如果数据没有准备好会立即返回,否则直到数据已复制到进程缓冲器后才产生信号并发送给进程;这一点和信号驱动式I/O不同,信号驱动式I/O是在数据报准备好后就通知进程,此时数据还未从内核复制到用户空间;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: