Linux下常用的IO模型

发布于:2025-02-10 ⋅ 阅读:(62) ⋅ 点赞:(0)

Linux下常用的IO模型:

1. 阻塞IO
    fgets
    read
    getchar
    fread
    fgetc
    recv
    recvfrom
    1. 让多个IO事件以同步方式处理,
    2. 多个IO事件之间互相影响
    3. CPU占有率低

2. 非阻塞IO
       将IO对应的文件描述符设置成非阻塞方式。
        O_NONBLOCK
        fcntl
     1.非阻塞一般搭配轮询方式同时监测多个IO
     2.cpu占有率高

3. 信号驱动IO
      SIGIO
     1.实现异步IO操作,节省CPU开销
     2.只能针对比较少的IO事件

4. IO多路复用(IO多路转接)*
       在不创建新的进程和线程的前提下, 在一个进程中,同时监测多个IO
    1. select
          1. 文件描述符集合以数组(位图)的方式保存,最多监测1024个文件描述符。
          2. 文件描述符集合创建在应用层,需要应用层和内核层反复拷贝
          3. 内核层返回整个文件描述符集合,需要用户层遍历查找到达事件的文件描述符
          4. 只能工作在水平触发模式(低速模式)
    2. poll
          1. 文件描述符集合以链表的方式保存,监测文件描述符可超过1024。
          2. 文件描述符集合创建在应用层,需要应用层和内核层反复拷贝
          3. 内核层返回整个文件描述符集合,需要用户层遍历查找到达事件的文件描述符
          4. 只能工作在水平触发模式(低速模式)
    3. epoll 
          1. 文件描述符集合以树型结构(红黑树)保存,监测文件描述符可超过1024, 提高了数据的查找速度。
          2. 文件描述符集合创建在内核层;
          3. 返回的是到达事件的文件描述符集合,无需遍历查找
          4. 可以工作在水平触发模式(低速模式),也可以工作在边沿触发模式(高速模式)

使用select实现IO多路复用的步骤:

1. 创建文件描述符集合
2. 添加关注的文件描述符到集合
3. 传递给内核,内核开始监测IO事件  select  
4. IO事件到达则返回结果

使用select实现IO多路复用的主要函数接口:

int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);
功能:通知内核监测IO事件并返回事件结果
参数:
        nfds:最大文件描述符+1
        readfds: 文件描述符读事件集合
        writefds:文件描述符写事件集合
        exceptfds:其他
        timeout : 超时时间
返回值:
    成功:返回达到的事件的个数
    失败:-1
    设置超时:超时时间到,但没有事件到达:0

       void FD_CLR(int fd, fd_set *set);
       int  FD_ISSET(int fd, fd_set *set);
       void FD_SET(int fd, fd_set *set);
       void FD_ZERO(fd_set *set);

使用epoll实现IO多路复用的主要函数接口:

int epoll_create(int size);
功能:创建epoll的文件描述符集合
参数:
        size:集合保存数据的最大个数
返回值:
       成功:返回一个文件描述符(代表集合)
       失败:-1

       int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
功能:对集合中的文件描述符进行操作
参数:
         epfd:文件描述符集合
          op:操作
                 EPOLL_CTL_ADD : 添加
                 EPOLL_CTL_DEL : 删除
                 EPOLL_CTL_MOD:修改

         fd : 要操作的文件描述符
         event:文件描述符事件结构体地址
                       EPOLL_CTL_DEL : 删除----》NULL

返回值:
     成功:0
      失败:-1

 int epoll_wait(int epfd, struct epoll_event *events,
                      int maxevents, int timeout);
功能:开始监测IO事件
参数:
      epfd:文件描述符集合
      events:  保存返回的事件集合的地址
      maxevents : 监测的文件描述符的个数
      timeout:超时时间
                   -1 :不设置超时时间
返回值:
       成功:返回实际到达的事件的个数
        失败:-1
       设置超时事件,超时没有事件到达:0

使用select实现TCP并发服务器:

         


网站公告

今日签到

点亮在社区的每一天
去签到