== Structure ==
I/O多路复用技术
==========
系统内核缓冲I/O数据,当某个I/O准备好后,系统通知应用程序该I/O可读或可写,这样应用程序可以马上完成相应的I/O操作,而不需要等待系统完成相应I/O操作,从而应用程序不必因等待I/O操作而阻塞。
优点:系统开销小,比Multithread。
水平触发(Level Triggered)
================
另外,select()和poll()将就绪的文件描述符告诉进程后,如果进程没有对其进行IO操作,那么下次调用select()和poll()的时候将再次报告这些文件描述符,所以它们一般不会丧失就绪的消息,这类方法称为水平触发(Level Triggered)。如果你不作任何操作, 内核还是会继承通知你的,所以,这类模式编程犯错误可能性要小一点。传统的select/poll都是这类模型的代表。
边缘触发(Edge Triggered
===============
epoll可以同时支撑水平触发和边缘触发(Edge Triggered,只告诉进程哪些文件描述符刚刚变成就绪状态,它只说一遍,如果我们没有采取行动,那么它将不会再次告诉,这类方法称为边缘触发),理论上边缘触发的性能要更高一些,但是代码实现相称复杂。
select
====
1 用fd_set,按位表示fd,最大1024.,通常是够用了。
2 U/K ,要复制数据。
epoll
====
1 没有fd的限制,网文说是链表的缘故。我觉得这就是select,自己的问题谁让你用bit对应fd呢,一点也不灵活。
2 mmap,减少U/K,之间的复制。
3 水平和边沿
== Depth exploration ==
select 的低效
========
1 描述符个数限制。
2 每次调用时要重复地从用户态读入参数。
3 每次调用时要重复地扫描文件描述符。
epoll为什么高效
========
1 只要拷贝一次fd 到内核,不用想select,每次调用都拷贝,烦死了。
2 没有fd数量限制
3 触发式,不用像select轮询。
4 返回结果,也简单明了。
-
int n = epoll_wait(epfd, events, 10, 100);
-
for (int i = 0; i < n;i++)
-
{
-
handleEvent(events[n]);
-
}
epoll 的使用流程
========
epoll_create 在eventpoll filesystem,
创建eventpoll得到efd。
epoll_ctl为我们要添加的fd创建epitem,加入到eventpoll的rbr中。
阅读(2635) | 评论(0) | 转发(0) |