Linux 下网络 IO 的多路复用
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Linux 下网络 IO 的多路复用,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3084字,纯文字阅读大概需要5分钟。
内容图文
![Linux 下网络 IO 的多路复用](/upload/InfoBanner/zyjiaocheng/949/355ee8da664b4079b2ce7eee8014f417.jpg)
2019-10-20
关键字:select 与 poll
在 Linux 系统下,IO 总共可以分为以下四种:
1、阻塞 IO;
2、非阻塞 IO;
3、IO多路复用;
允许同时对多个 IO 进行控制。
4、信号驱动 IO;
一种异步通信模型。前面三种 IO 都是同步型的,唯这一种是异步型的。
阻塞 IO
所谓阻塞 IO 就是在调用相关函数时,程序的运行指针会暂停往下执行,直至这个 IO 操作有结果返回为止。简单来说就是我发起一个 IO 操作请求,你有数据就返回给我,没数据我就等你到有数据为止。
阻塞型 IO 是最普遍使用的 IO 模式,大部分的程序都是使用这一模式的。套接字在缺省情况下使用的就是阻塞 IO 模式。
常见的阻塞模式函数有:read, recv, recvfrom, write, send, accept, connect。 这里需要强调,sendto 函数是非阻塞型的。
非阻塞 IO
非阻塞型 IO 比较干脆。当它发起一个 IO 请求时,若 IO 有数据就返回结果,若无数据则程序指针就继续往下执行了,不会死等的。
我们可以通过两个函数来切换阻塞型与非阻塞型 IO。
1、fcntl()
假设我们需要将阻塞型 IO 设置为非阻塞型 IO。
int flag;
flag = fcntl(sockfd, F_GETFL, 0);
flag |= O_NONBLOCK;
fcntl(sockfd, F_SETFL, flag);
这样一来一去,就将 IO 形式给更改过来了。
2、ioctl()
int b_on = 1;
ioctl(sock_fd, FIONBIO, &b_on);
IO 多路复用
IO 多路利用其实就是 C 编程中的 select/poll 模型和 epoll 模型。
Select 函数:
select 函数的作用就是将原本需要单独分别监听阻塞资源统一交由 select 来监听。每当被 select 所监听的资源有数据波动时,select 会采用轮询的方式去找出哪个阻塞资源有数据过来了。并将这些有数据波动的资源保存起来,然后中断 select 函数的阻塞态,执行后面的代码。select() 函数的原型如下:
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
这个函数是一个阻塞函数。当它返回值 0 时表示等待超时。返回值 -1 时表示等待失败。返回值大于 0 时表示成功监测到信号。
参数 nfds 是指 fd 的个数。由于在 Linux 中,文件描述符总是顺序递增增长的,因此这个参数也可以填入最大文件描述符号的值再加一。即 maxfd + 1。
参数 readfds 是读集合。
参数 writefds 是写集合。
参数 exceptfds 是异常集合。
参数 timeout 是超时时长。
fd_set 是系统定义的用于存放文件描述符的信息的结构体,可以通过以下几个函数来设定:
1、void FD_ZERO(fd_set *fdset);
对指定集合清零。
2、void FD_SET(int fd, fd_set *fdset);
将 fd 加入到 fdset 集合中去。
3、void FD_CLR(int fd, fd_set *fdset);
从集合中清除指定的 fd。
4、int FD_ISSET(int fd, fd_set *fdset);
判断指定的 fd 是否可以读写。
对于 select 函数中,writefds 与 exceptfds 通常都填 NULL。同时,对于 select() 之前与之后的 fd_set 集合,它所包含的内容是不一样的。在 select() 之前,我们会往 fd_set 集合中填入所有我们想监听的资源 fd,但在 select() 之后,对应的 fd_set 集合中的数据就已经发生了变化。通常可以理解为只有有数据波动的资源集合才会出现在 select() 以后的代码中。
以下是一个运用 select() 来复用 TCP 编程的伪代码:
poll 函数:
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
函数执行成功时返回大于0的值,失败时返回 EOF,超时返回值0。
参数 pollfd 是一个系统结体体,它的原型如下:
struct pollfd {
int fd; //要监听的文件描述符号。
short events; // 请求的事件。
short revents; // 返回的事件。
};
参数 nfds 与 timeout 就不再赘述了。
以下是一个示例程序,程序来自于 https://www.jianshu.com/p/6a6845464770
epoll 函数:
略。
信号驱动 IO
略。
内容总结
以上是互联网集市为您收集整理的Linux 下网络 IO 的多路复用全部内容,希望文章能够帮你解决Linux 下网络 IO 的多路复用所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。