Linux网络——IO模型和多路转接

通常所谓的IO,其本质就是等待通信和进行通信,即IO = 等 + 拷贝。

那么想要做到高效的IO,就要在单位时间内,减少“等”的比重。


一.五种IO模型

  1. 阻塞 IO: 在内核将数据准备好之前, 系统调用会一直等待. 所有的套接字, 默认都是阻塞方式。阻塞 IO 是最常见的 IO 模型。
  2. 非阻塞 IO: 如果内核还未将数据准备好, 系统调用仍然会直接返回, 并且返回EWOULDBLOCK 错误码. 非阻塞 IO 往往需要程序员循环的方式反复尝试读写文件描述符, 这个过程称为轮询. 这对 CPU 来说是较大的浪费, 一般只有特定场景下才使用。
  3. 信号驱动 IO: 内核将数据准备好的时候, 使用 SIGIO 信号通知应用程序进行 IO 操作.
  4. IO 多路转接: 和阻塞 IO 类似. 核心在于 IO 多路转接能够同时等待多个文件描述符的就绪状态。
  5. 异步 IO: 由内核在数据拷贝完成时, 通知应用程序(而信号驱动是告诉应用程序何时可以开始拷贝数据)。

此处展开分享一下非阻塞IO。 


二.非阻塞IO

系统和网络中的文件描述符,其默认情况下都是阻塞IO,下面来看怎么将其设置为非阻塞IO。


1.fcntl函数

#include <unistd.h>

#include <fcntl.h>

int fcntl(int fd, int cmd, ... /* arg */ );

fcntl 函数有 5 种功能:

  • 复制一个现有的描述符(cmd=F_DUPFD.
  • 获得/设置文件描述符标记(cmd=F_GETFD F_SETFD).
  • 获得/设置文件状态标记(cmd=F_GETFL F_SETFL).
  • 获得/设置异步 I/O 所有权(cmd=F_GETOWN F_SETOWN).
  • 获得/设置记录锁(cmd=F_GETLK,F_SETLK F_SETLKW).

此处只是用第三种功能, 获取/设置文件状态标记, 就可以将一个文件描述符设置为非阻塞。


2.代码实现非阻塞

void SetNoBlock(int fd)
{
    int fl = fcntl(fd, F_GETFL);
    if (fl < 0)
    {
        perror("fcntl");
        return;
    }
    fcntl(fd, F_SETFL, fl | O_NONBLOCK);
}

使用 F_GETFL 将当前的文件描述符的属性取出来(这是一个位图)。

然后再使用 F_SETFL 将文件描述符设置回去. 设置回去的同时, 加上一个 O_NONBLOCK 参数,表示为非阻塞

前边提到,在非阻塞IO下,如果数据没有就绪,那么IO就会以出错的形式返回,那么如何区分到底是数据没有就绪,还是真的出错了呢???

通过判断errno错误码,如果错误码为EWOULDBLOCK,表示数据没有就绪,此时可以设计程序去做其他事,并通过轮询方式去检测数据是否就绪,反之则为真的出错,程序退出。

此外,如果进程长期阻塞,可能会收到系统的信号,中断程序运行,此时返回的错误码为EINTR,所以如果不想程序被系统中断,就可以通过此错误码在做判断。


三.多路转接

多路转接,即等待多个fd上的新事件就绪,然后通知程序员,事件已经就绪,可以进行IO拷贝了。


1.select

(1)概述

系统提供 select 函数来实现多路复用输入/输出模型。

  • select 系统调用是用来让我们的程序监视多个文件描述符的状态变化的;
  • 程序会停在 select 这里等待,直到被监视的文件描述符有一个或多个发生了状态改变;

IO = 等 + 拷贝,select负责的就是等待,并且是等待多个新事件的到了。


(2)接口

#include <sys/select.h>

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, str

评论 80
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

很楠不爱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值