DAY7-同步式IO和IO多路复用

114 阅读2分钟

十一.Linux系统中的IO模型

1.分类

(1)同步阻塞式IO

应用层调用read/write时,内核同步响应,如果内核 读/写 条件不满足,应用程序将被阻塞直到 读/写 条件满足,条件满足时结束阻塞,阻塞过程中睡眠,让出CPU。

(2)同步非阻塞时IO

应用层调用read/write时,内核同步响应,不管读写条件是否满足,都立即返回。

image-20220801235851122

(3)IO多路复用

阻塞的不是读/写操作本身,而是阻塞描述符的监控,当描述符的状态变为可读/写之后,解除描述符监控的阻塞状态,应用层再进行读写操作。

image-20220801235857835

(4)异步通知

对描述符添加异步通知的标志,当内核读/写条件满足时,内核通过信号/回调函数通知应用程序。

image-20220801235904192

2.同步IO的实现

(1)在应用程序中如何选择阻塞式/非阻塞式

默认使用阻塞式IO,如果要选择非阻塞式,必须在open时加上非阻塞标志 ------ O_NONBLOCK

int fd = open(文件路径,O_RDWR);//阻塞式
int fd = open(文件路径,O_RDWR|O_NONBLOCK);//非阻塞式

(2)在内核中如何实现阻塞式/非阻塞式

内核中通过判断标志(struct file结构),内核中的非竞态阻塞使用等待队列来实现。

3.IO多路复用

内核IO多路复用的实现对应用户空间的 select poll epoll,其对应的内核接口时poll函数,也就是实现file_operations中的poll函数。

(1)内核中poll函数的实现

需要包含的头文件:

#include <linux/poll.h>

poll函数:

unsigned int cdd_poll(struct file *filp, struct poll_table_struct *wait)
{
    unsigned int mask;
​
    //声明造成阻塞的等待队列
    poll_wait(filp,等待队列,wait);
    //poll_wait(filp, &wqh, wait);
    //poll_wait(filp, &rqh, wait);down(&sema);
​
    //根据当前的情形决定哪些操作可用
    if(len>0){//可读
        mask |= POLLIN|POLLRDNORM;
    }
    if(len<128){//可写
        mask |= POLLOUT|POLLWRNORM;
    }
​
    //...........
    
    up(&sema);
​
    return mask;
}

(2)poll和epoll的用法

poll:

#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
//前两个参数是传入struct pollfd数组,第三个参数是超时时间(传入负数表示不超时)
struct pollfd {
   int   fd;         /*要监控的描述符*/
   short events;     /*要监控的事件*/
   short revents;    /*返回事件*/
};

epoll:

#include <sys/epoll.h>
​
epoll_create =======> epoll_ctl =======> epoll_wait =======>IO操作
创建专用描述符       添加要监控的事件     阻塞等待事件发生
​
struct epoll_event {
   uint32_t     events;    /*要监控的事件*/
   epoll_data_t data;      /*额外数据*/
};
​
typedef union epoll_data {
   void    *ptr;
   int      fd;
   uint32_t u32;
   uint64_t u64;
} epoll_data_t;
​
int epoll_create(int size);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
int epoll_wait(int epfd, struct epoll_event *events,
              int maxevents, int timeout);

select,poll,epoll机制的区别

image-20220801235919574