【转载】Linux下套接字学习

时间:2024-10-27 19:06:38

感觉这个系列还不错,学习一下。

先看的是第三篇:

http://blog.****.net/gatieme/article/details/46334337

《 Linux下套接字详解(三)----几种套接字I/O模型》

POSIX关于同步和异步IO的描述:

A synchronous I/O operation causes the requesting process to be blocked until that I/O operation completes;

An asynchronous I/O operation does not cause the requesting process to be blocked;

可以总结为一下几点

同步 就是我调用一个功能,该功能没有结束前,我死等结果。只能顺序执行。
异步 就是我调用一个功能,不需要知道该功能结果,该功能有结果后通知我(回调通知),往往用回调函数或者其他类方式实现。
阻塞 就是调用我(函数),我(函数)没有接收完数据或者没有得到结果之前,我不会返回。
非阻塞 就是调用我(函数),我(函数)立即返回,而当我准备完毕时,通过select通知调用者。 同步IO和异步IO的区别就在于:数据拷贝的时候进程是否可以被阻塞
阻塞IO和非阻塞IO的区别就在于:应用程序的调用是否能立即返回

信号驱动I/O (signal driven I/O (SIGIO))

为了让套接字描述符可以工作于信号驱动I/O模式,应用进程必须完成如下三步设置: 
1.注册SIGIO信号处理程序。(安装信号处理器) 
2.使用fcntl的F_SETOWN命令,设置套接字所有者。(设置套接字的所有者) 
3.使用fcntl的F_SETFL命令,置O_ASYNC标志,允许套接字信号驱动I/O。(允许这个套接字进行信号输入输出)

必须保证在设置套接字所有者之前,向系统注册信号处理程序,否则就有可能在fcntl调用后,信号处理程序注册前内核向应用交付SIGIO信号,导致应用丢失此信号。下面的程序片段描述了怎样为套接字设置信号驱动I/O:

sigaction 函数:
int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact)

按照上面POSIX关于同步和异步的定义,之前所述的blocking IO,non-blocking IO,IO multiplexing都属于synchronous IO。

有人可能会说,non-blocking IO并没有被block啊。这里有个非常“狡猾”的地方,定义中所指的”IO operation”是指真实的IO操作,就是例子中的recvfrom这个系统调用。

non-blocking IO在执行recvfrom这个系统调用的时候,如果kernel的数据没有准备好,这时候不会block进程。但是当kernel中数据准备好的时候,recvfrom会将数据从kernel拷贝到用户内存中,这个时候进程是被block了,在这段时间内进程是被block的。

而asynchronous IO则不一样,当进程发起IO操作之后,就直接返回再也不理睬了,直到kernel发送一个信号,告诉进程说IO完成。在这整个过程中,进程完全没有被block。

UNP中总结的IO模型有5种之多:阻塞IO,非阻塞IO,IO复用,信号驱动IO,异步IO。

非阻塞IO ,IO请求时加上O_NONBLOCK一类的标志位,立刻返回,IO没有就绪会返回错误,需要请求进程主动轮询不断发IO请求直到返回正确。

IO复用同非阻塞IO本质一样,不过利用了新的select系统调用,由内核来负责本来是请求进程该做的轮询操作。看似比非阻塞IO还多了一个系统调用开销,不过因为可以支持多路IO,才算提高了效率。

信号驱动IO,调用sigaltion系统调用,当内核中IO数据就绪时以SIGIO信号通知请求进程,请求进程再把数据从内核读入到用户空间,这一步是阻塞的。

异步IO,如定义所说,不会因为IO操作阻塞,IO操作全部完成才通知请求进程。

Linux下的asynchronous IO其实用得不多,从内核2.6版本才开始引入。先看一下它的流程: 
用户进程发起read操作之后,立刻就可以开始去做其它的事。而另一方面,从kernel的角度,当它受到一个asynchronous read之后,首先它会立刻返回,所以不会对用户进程产生任何block。然后,kernel会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,kernel会给用户进程发送一个signal,告诉它read操作完成了。

再复习一下下面这张图:

【转载】Linux下套接字学习

(完)