(1)同步阻塞式IO
(2)同步非阻塞式IO
(3)IO多路复用
(4)异步通知
当进行读写操作时,如果没有读的数据或者写的空间满了,导致读写操作阻塞,这种IO方式就叫同步阻塞式IO,当数据重新变得可读/可写,阻塞解除。
网络socket通信的默认IO方式就是同步阻塞式IO
当进行读写操作时,不管是否读写成功,都立即返回。
如何将socket通信设置为同步非阻塞式IO?
IO多路复用同时监控多个描述符,找出其中可以进行读操作/写操作/有错误的描述符。
实现IO多路复用的接口:select,poll,epoll。
参考例程:
过程确实很多,想轻松写出来难度有点大,对于我们来说理解会用就行。
poll类似于select,使用方法和实现机制略有区别,select使用描述符集合,poll使用事件数组。
epoll相比于poll和select来说,效率更高,核心函数是epoll_wait。
epoll_create-->epoll_ctl-->epoll_wait-->IO操作
创建epoll专用描述符->添加要监控的描述符->等待活动事件发生
1.select和poll在底层操作没有区别,唯一的区别是监控描述符个数的限制, select只能监控一个描述符集合范围内的描述符,poll理论上没有监控的个数限制
2.select,poll和epoll都需要不停地轮询所有监控的描述符,直到有描述符变为就绪, 期间会有睡眠和唤醒的多次交替,但是epoll在描述符就绪时,调用回调函数,把就绪的 描述符放入到就绪链表中,并唤醒epoll_wait的进程。虽然都有睡眠和唤醒的交替,但是 select和poll在唤醒后要去遍历所有监控的描述符,而epoll唤醒后只需要判断就绪链表 是否为空即可,这样节省了大量的CPU时间,提高了效率。
3.select和poll每次调用时都要把所有监控的描述符从用户态拷贝到内核态,而epoll只要 拷贝(epoll_ctl)一次,这样也节省了不少的开销。
异步通知不阻塞任何操作,用户进程添加一步通知之后立即返回,当IO条件满足时内核通过用户进程发送信号(SIGIO)的方式通知用户进程完成IO操作。
异步通知的实现:
(1)捕获信号SIGIO,信号处理函数中完成具体的IO操作
(2)指定当前进程的文件属主
fcntl(fd,F_SETOWN,getpid());
(3)为文件描述符添加FASYNC标志
flags=fcntl(fd,F_GETFL);
fcntl(fd,F_SETFL,flags|FASYNC);
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ri-ji/7873.html