当前位置:首页 >  开发者 >  【转载】Linux下套接字学习

【转载】Linux下套接字学习

感觉这个系列还不错,学习一下。先看的是第三篇:http://blog.csdn.net/gatieme/article/details/46334337《Linux下套接字详解(三)----几种套接字I/O模型》POSIX关于同步和

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

先看的是第三篇:

http://blog.csdn.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操作完成了。 

再复习一下下面这张图:

 (完)

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,
如果涉及侵权请联系站长邮箱:support@yingtwo.com 进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

原文链接:none

最近更新

LinuxCentOS7.x离线安装PostgreSQL操作手册
LinuxCentOS7.x离线安装PostgreSQL操作手册

一、准备环节rpm-qa|greppostgr...

h3c路由器怎么设置
h3c路由器怎么设置

h3c路由器设置方法:工具/原料:华为Mate...

南航里程有什么用处?
南航里程有什么用处?

每一次旅客与南航同行,只要在购票或者办理乘机手...

陈睿求变,B站依旧艰难
陈睿求变,B站依旧艰难

雷达财经鸿途出品 文|莫恩盟 编|深海在6月2...

超级女英雄哪个厉害
超级女英雄哪个厉害

漫威中有数不清的超级英雄,而在我们讨论最强大的...

台电平板屏幕多少钱
台电平板屏幕多少钱

尊敬的台电用户:您好,X80HD的外屏是120...

嘉实多和昆仑哪个好
嘉实多和昆仑哪个好

你好!嘉实多机油是业界最好的,比昆仑机油贵很多...

68.C++中的const
68.C++中的const

编写程序过程中,我们有时不希望改变某个变量的值...

封神榜哪个版本游戏
封神榜哪个版本游戏

PC上的荡神志、刀剑封魔录、封神榜之英雄无敌P...