I/O多路复用

其实这些在UNP上都讲过,只是用自己的话把自己的一些理解写下来加深一些印象。

I/O复用的主要思想就是先构造一张描述符的列表,然后调用一个函数直到这些描述符中的一个已经准备好I/O操作时,该函数就返回,同时告诉进程那些描述符准备好I/O操作了。

在linux系统上支持I/O复用的系统调用有select, pselect, poll, epoll, 而epoll是在linux 2.6才加入的,相较与传统的方法,效率有了很大的提升。首先是传统方法。

  1. select和pselect
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask);

分析select会让我们对该函数有更多的认识。传向该函数的参数通知内核一些信息,我们关心哪些描述符以及这些描述符的状态,还有愿意等待的时间。

返回时内核则会告诉我们哪些描述符已就绪和已就绪描述符的数量。

这两个函数功能差不多,但仔细看两个函数最后的参数可以看出区别来。首先select和peslect超时值类型不同,并且pselect的时间值不能够被修改,同时pselect指定更加精准的定时。同时pselect添加了信号屏蔽字,执行该函数时会以原子操作安装信号屏蔽字,函数返回时恢复之前的信号屏蔽字。

同时这两个函数会根据超时值等待不同的时间:

  • 一直等待:在有一个描述符准备好或信号中断返回,否则一直阻塞,时间值为NULL。
  • 等待固定时间:在有一个描述符准备好或超时返回,时间值为具体值。
  • 不等待:检查描述符后马上返回,时间值为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);
这几个宏比较简单,在man 文档上大家可以自行查看。

       2.  poll

#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);

struct pollfd {
	int fd;                  /* file descriptor */
        short events;     /* requested events */
        short revents;    /* returned events */
};

poll的第一个参数指向一个pollfd数组的指针,我觉得用fds[]应该更好,用指针会给人误解为一个指向pollfd结构体的指针,其实是指向一个pollfd结构体数组,每个数组元素包含描述符,描述符状态,其中ndfs是pollfd数组元素的个数,在函数返回时,内核会根据描述符的状态改变设置revents值,并且返回已就绪的描述符数目。

另外一个就是时间值,它不同于select采用结构体,而就是用一个整型数来表示poll等待多长时间,其他操作与select没什么不同:

  • timeout == -1:一直等待
  • timeout == 0:不等待
  • timeout  > 0:等待固定时间

对此,我们可以发现select和poll函数实现的方式不同,poll不是为每种状态设置描述符集,而是设置pollfd结构数组,每个元素包含描述符及我们所关心的状态。到此,传统的I/O复用就这些了,有些具体例子可以参考UNP第6章。另外就是epoll了,很重要的,毕竟现在用的较多嘛,下回再详细说吧。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值