在 AIX 上通过 pollset 接口实现高效的 I/O
2009-09-05 00:00:00 来源:WEB开发网清单 4. 如何启动 poll
channel.register(selector, SelectionKey.OP_READ);
select() 调用返回一个文件描述符列表,对于每个文件描述符至少注册了一个事件。然后,应用程序只能对这些文件描述符执行 I/O 操作。这种方法会消除内核和用户空间之间的大量系统调用和数据复制,从而显著降低开销。
选择器在内部调用一个本机 poll() 函数(见 清单 5),这个函数支持在一组文件描述符上多路复用输入和输出:
清单 5. poll() API 的签名
int poll(struct pollfd fds[], nfds_t nfds, int timeout);
pollset 方法:AIX 解决 poll () /select () 可伸缩性问题的方法
但是,传统的 poll 方法有可伸缩性问题;它不太适合处理大量文件描述符。根本问题是,随着文件描述符数量的增加,每个 poll 操作所需的工作量会线性增加。为了提高可伸缩性,已经提出了许多新的 API,比如 /dev/poll、实时信号、I/O 完成端口、/dev/epoll 和内核队列。对于哪个 API 是最好的长期解决方案,有许多争论(见 [POLLCMP])。
poll() 的哪些方面影响可伸缩性?
每个 poll() 调用都提供要 poll 的文件描述符列表。对于每个调用,都要把这个列表复制到内核空间中。图 1 中红色的事件表示这些重复的复制。
poll 一个对象需要两步:首先在文件描述符上建立一个持有计数,然后调用与这个文件描述符相关联的操作。
异步和同步 poll 之间的主要路径长度差异是,分配和最终清除控制块。
作为 poll 操作的最后一步,要清除所有控制块。必须从与块相关联的对象中删除每个控制块。这要求 poll 方法锁住对象。
更多精彩
赞助商链接