I/O多路复用

select,poll,epoll都是IO多路复用的机制。

I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。

对于新的输入/输出, 怎么管理大量的文件描述符(fd),我们每次需要监控大量的文件描述符?

Servers need to watch a lot of file descriptors

假如你作为一个web服务器。每次你通过 accept系统回调 接收一个连接,你得到一个新的fd代表这个连接。

如果你是一个web服务器,你需要同时处理成千上万的访问。你需要去知道人们发送的新的数据在哪个连接,因此你才能去处理和响应他们。

一个基础循环:

for x in open_connections:
	if has_new_input(x):
		process_input(x)

但是这样你浪费了太多的cpu去询问“有没有更新?”。另一种方式仅仅需要去问Linux kernel “这有100个fd, 当他们更新的时候告诉我!".

你可以通过三种系统调用询问Linux去监控大量的fd.分别是poll, epoll, select

首先: select & poll

这两种系统调用在任何Unix系统,但是epoll只在Linux
1. 给它们一个获取信息的文件描述列
2. 它们告诉你哪些有读/写数据
poll 和 select 根本上使用相同的代码
select.c

  • 它们调用大量相同的函数。poll返回大量可能的文件描述符的结果,比如(POLLRENORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR,
    但是select 仅仅返回" there input / there’s output / there’s an error".
  • poll能够比select 表现的更好,当处理少量的文件描述符。
int ppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *tmo_p, const sigset_t *sigmask)

int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask);

poll , 你能告诉他"我想监控: 1, 3, 8, 19…"(这是pollfd参数)
select, 你能告诉他"网线监控19个fd. 这个3 bitsets 监控 reads / writes / exceptions",因此当你运行,它循环0-19 fd, 即使你仅仅对于他们中的4个感兴趣。

为什么我们不适用poll 和 select?

一旦我们调用select() 或者 poll(), 内核检查所有的特别的准备好的fd去监控。
当有大量密集范围的fd, 这是需要大量的资源(做了很多多余的事).

基础: 每次调用select or poll, 内核需要从scratch核对,无论你的fds时候可以写。
内核不记忆fd列表支持的监控.

Signal-driven I/O

The book actually describes 2 ways to ask the kernel to remember the list of file descriptors it’s supposed to be monitoring: signal-drive I/O and epoll. Signal-driven I/O is a way to get the kernel to send you a signal when a file descriptor is updated by calling fcntl. I’ve never heard of anyone using this and the book makes it sound like epoll is just better so we’re going to ignore it for now and talk about epoll.

level-triggered vs edge-triggered
Before we talk about epoll, we need to talk about “level-triggered” vs “edge-triggered” notifications about file descriptors. I’d never heard this terminology before (I think it comes from electrical engineering maybe?). Basically there are 2 ways to get notifications

get a list of every file descriptor you’re interested in that is readable (“level-triggered”)
get notifications every time a file descriptor becomes readable (“edge-triggered”)
what’s epoll?
Okay, we’re ready to talk about epoll!! This is very exciting to because I’ve seen epoll_wait a lot when stracing programs and I often feel kind of fuzzy about what it means exactly.

The epoll group of system calls (epoll_create, epoll_ctl, epoll_wait) give the Linux kernel a list of file descriptors to track and ask for updates about whether

Here are the steps to using epoll:

Call epoll_create to tell the kernel you’re gong to be epolling! It gives you an id back
Call epoll_ctl to tell the kernel file descriptors you’re interested in updates about. Interestingly, you can give it lots of different kinds of file descriptors (pipes, FIFOs, sockets, POSIX message queues, inotify instances, devices, & more), but not regular files. I think this makes sense – pipes & sockets have a pretty simple API (one process writes to the pipe, and another process reads!), so it makes sense to say “this pipe has new data for reading”. But files are weird! You can write to the middle of a file! So it doesn’t really make sense to say “there’s new data available for reading in this file”.
Call epoll_wait to wait for updates about the list of files you’re interested in.
performance: select & poll vs epoll
In the book there’s a table comparing the performance for 100,000 monitoring operations:

operations | poll | select | epoll

10 | 0.61 | 0.73 | 0.41
100 | 2.9 | 3.0 | 0.42
1000 | 35 | 35 | 0.53
10000 | 990 | 930 | 0.66
So using epoll really is a lot faster once you have more than 10 or so file descriptors to monitor.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值