Linux:一切皆文件
Linux将所有外部设备都看做文件,对文件的读写操作会调用内核提供的系统命令,返回一个file descriptor(fd,文件描述符)。
Linux也把socket当成文件,称为socketfd(socket描述符)。
描述符是一个数字,该数字指向内核中的一个结构体(该结构体包含文件路径,数据区等属性)。
模型一:阻塞I/O模型
在进程空间中调用recvfrom,该系统调用直到数据包到达且被复制到应用进程的缓冲区中或者发生错误时才返回,次期间将会一直等待。
进程从调用recvfrom方法开始到recvfrom方法返回的期间都是被阻塞的。
模型二:非阻塞I/O模型(轮询式)
调用recvfrom方法后,如果内核该缓冲区没有数据,就直接返回一个EWOULDBLOCK错误。
模型三:I/O复用模型(select/poll)
Linux提供了select/poll函数,进程通过将一定数量的fd传递给select/poll函数。
select函数会被阻塞,select/poll函数侦测多个fd是否处于就绪状态。
select/poll是顺序扫描fd是否就绪的,而且支持的fd数量是有限。
模型四:I/O复用模型(epoll)
Linux提供了一个epoll函数,epoll函数使用事件驱动方式代替顺序扫描,因此性能更高。当有fd就绪时,立即调用回调函数。
模型五:信号驱动I/O模型
先开启套接口的信号驱动I/O功能,sigaction函数安装一个信号处理函数(sigaction函数立即返回,进程继续工作,它是非阻塞的)。
当数据准备就绪时,就为该进程生成一个SIGIO信号,通过信号回调通知应用程序调用recvfrom来读取数据。
异步I/O
调用系统函数通知内核启动某个操作,并让内核在整个操作完成后(包括将数据从内核复制到用户自己的缓冲区)通知我们。
Linux I/O模型的总结
IO主要涉及两步操作:
等待内核数据准备完成
数据从内核复制到用户空间
I/O模式的改进就是不断减少在这两步所花的时间。
阻塞I/O: 两个阶段阻塞
非阻塞I/O: 待内核数据准备完成期间轮询(等同阻塞,也可以多个I/O一起轮询) ,数据从内核复制到用户空间阻塞
I/O复用: 等待内核数据准备完成期间可以多个I/O轮询,数据从内核复制到用户空间阻塞
信号驱动I/O:数据从内核复制到用户空间期间线程阻塞
异步I/O:完全不阻塞
Linux信号驱动I/O与异步I/O的区别
信号驱动I/O:内核通知程序何时可以开始一个I/O操作;
异步I/O: 内核通知程序I/O操作何时已完成,也就是说数据准备和数据复制到用户空间都是系统完成的。
文章来源于:优秀的IT运维管理系统云雀运维