Linux——I/O复用
来源:互联网 发布:天猫淘宝网创始人是谁? 编辑:程序博客网 时间:2024/05/18 01:13
缅怀Stevens大师。
最好的参考资料:
1.师从互联网。
2.UNP v1第6章 。
3,man select、man pselect、man epoll、man poll
第一条:概述
复用是个伟大的概念呀!什么是I/O复用(I/O multiplexing)呢?具体点就是当你编写的程序需要同时处理多个描数字(socket或file或device),你又不知道什么时候应该(比方说有数据可以读了)去操作(读/写)哪个描数字。这时候I/O复用就需要登场了。
UNPv1给出了定义。I/O复用是一种让进程预先“警告”内核能力,使得内核一旦发现进程预先告知时指定的一个或多个I/O条件(就是描述符)就绪(可以读/写了),内核就通知进程。linux有4个调用可实现I/O复用:select、poll继承自Unix系统。pselect是select到Posix版。epoll是linux2.6内核特有的。
第二条:I/O模型
(0)一般输入操作通常包含如下两个阶段,请谨记:
1、等待数据准备好。
2、内核到进程的数据拷贝。
(0.1)例如对于socket上的输入操作:
1、数据从网络到达,当数据到达时,收集到内核中相应的缓冲区。
2、从内核缓冲区拷贝数据到进程端口缓冲区中。
(1)UNPv1当中总结了Unix的I/O模型:
1、阻塞I/O:进程被阻塞I/O系统调用上(read、write、sendto、recvfrom等等)直到I/O条件就绪(可读/写或异常)处理完,处理后从I/O系统调用返回进程。
2、非阻塞I/O。就是采用轮询方式调用非阻塞I/O系统调用。
3、I/O复用。
4、多线程阻塞I/O。把要处理的描数字分配到多个线程中,每个线程独立地调用I/O系统调用,独立处理。
5、信号驱动I/O。类似于I/O复用,当I/O条件就绪时使用信号通知进程去调用I/O系统调用处理。
6、异步I/O。通过aio_read告诉内核怎么处理,我们就不管了,内核处理完了后发个信号告诉我们,也可以用其他方式在处理完通知我们。
注:I/O系统调用是否阻塞,仅取决于他们操作的描数字是否是阻塞的。fcntl可设定。
(2)这6种I/O模型分为2类:
同步I/O模型:第1~5 I/O模型。这5种I/O模型,说到底,I/O调用还是要用户进程自己调用,被阻塞。
异步I/O模型:第6种I/O模型。I/O调用由内核执行,进程不被阻塞。
Posix关于同步I/O(synchronous I/O操作、异步I/O(asynchronous I/O)操作这两个术语的定义如下:
同步I/O操作:导致请求进程阻塞,直到I/O操作完成。
异步I/O操作:不导致进程阻塞。
注:鉴别是否是异步I/O操作,只要看I/O操作是谁执行。
第三条:pselect、select
#include <sys/select.h>
(0)int pselect(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict errorfds,
const struct timespec *restrict timeout, const sigset_t *restrict sigmask);//select的Posix版。
int select(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict errorfds,
struct timeval *restrict timeout);
(0.1)参数nfds:指定待测试描述字(就是描述符)的个数(不是最大值,概念上一定要区分),因为描述符是从0开始的,所以他的值就是待测试的最大描述符加1(多一个0)。
(0.2)参数readfds、writefds、errorfds:3个参数都是fd_set类型。这3个参数在函数调用地不同时段有两种用途:
(0.2.1)作为参数传入:我们把关心的描述符按照关心事件的事件类型分别放入其中。怎么放?见下。
(0.2.2)作为函数返回时的返回值:这3个参数装载这我们关心并且I/O条件就绪的描述符,未就绪的描述被清楚了。所以每次调用select时都要重新设置这三个参数,这非常重要。
(0.3)参数timeout:select和pselect中地类型,超时间类型分别:
/* POSIX.1b structure for a time value. This is like a `struct timeval' but has nanoseconds instead of microseconds. */
struct timespec {// 使用时加上-D__need_timespec
__time_t tv_sec;/* Seconds. */
long int tv_nsec;/* Nanoseconds. */纳秒。
};
/* A time value that is accurate to the nearest microsecond but also has a range of years. */
struct timeval {
__time_t tv_sec;/* Seconds. */
__suseconds_t tv_usec;/* Microseconds. */微妙。
};
(0.4)参数sigmask:信号屏蔽掩码。
(1)描述符fd和描述符集合fdset操作宏:
void FD_CLR(int fd, fd_set *fdset);//congfdset删除fd。
int FD_ISSET(int fd, fd_set *fdset);//测试fd是否在fdset当中
void FD_SET(int fd, fd_set *fdset);//向fdset添加fd
void FD_ZERO(fd_set *fdset);//清零,类似bzero。
第四条:poll
#include <poll.h>
(0)int poll(struct pollfd fds[], nfds_t nfds, int timeout);//epoll是poll的增强版
(0.1)参数fds是指向struct pollfd的数组。他是poll的核心。
struct pollfd{/* Data structure describing a polling request. *///每个描述符对应一个struct pollfd结构。
int fd;/* File descriptor to poll. *///我们关心的描述符。
short int events;/* Types of events poller cares about. */ //描述符关心的事件
short int revents;/* Types of events that actually occurred. *///poll返回时,返回描述符fd发生的时间。
};
成员events和revents的值如下:
/* Event types that can be polled for. These bits may be set in `events' to indicate the interesting event types; they will appear in `revents' to indicate the status of the file descriptor. */
#define POLLIN0x001/* There is data to read. *///可读
#define POLLPRI0x002/* There is urgent data to read. *///带外数据到达
#define POLLOUT0x004/* Writing now will not block. */可写
#if defined __USE_XOPEN || defined __USE_XOPEN2K8 /* These values are defined in XPG4.2. *///很少用
# define POLLRDNORM0x040/* Normal data may be read. *///一般数据可读
# define POLLRDBAND0x080/* Priority data may be read. *///优先级带数据可读
# define POLLWRNORM0x100/* Writing now will not block. *///一般数据可读
# define POLLWRBAND0x200/* Priority data may be written. *///优先级数据可写
#endif
#ifdef __USE_GNU/* These are extensions for Linux. */
# define POLLMSG0x400
# define POLLREMOVE0x1000
# define POLLRDHUP0x2000
#endif
/* Event types always implicitly polled for. These bits need not be set in `events', but they will appear in `revents' to indicate the status of the file descriptor. */
#define POLLERR0x008/* Error condition. */错误
#define POLLHUP0x010/* Hung up. */挂起
#define POLLNVAL0x020/* Invalid polling request. *///无效描述符等
(0.2)参数nfds:指名数组大小。
(0.3)参数timeout:超时时间。取值如下,单位为毫秒:
INFTIM:永远等待。linux没有定义此值,手动定义为-1即可。
0:立即返回,不阻塞进程。
>0:等待指定毫秒数。
第五条:FAQ
1、epoll是poll的加强版。
2、poll没有select 的描述符上限限制。描述符个数上限只和内存大小结构,即内存中struct pollfd 的个数。
- Linux——I/O复用
- linux复习——I/O复用
- Linux I/O复用
- Linux 高性能服务器编程——I/O复用
- Linux高性能服务器编程——I/O复用
- Linux高性能服务器编程——I/O复用
- Linux高性能服务器编程——I/O复用
- Linux I/O复用——select系统调用
- Linux I/O复用 —— epoll部分源码剖析
- linux异步I/O——AIO
- Linux I/O复用 epoll
- Linux设备驱动程序——I/O端口和I/O内存
- Linux内核学习笔记十一——I/O层和I/O调度机制
- Linux I/O performance monitoring utility —— I/O 性能检测软件
- Linux学习总结(四)——标准I/O与文件I/O
- Linux学习总结——linux I/O进阶
- I/O复用——select
- I/O复用——聊天室程序
- 使用SMTP发送邮件
- ehcache
- 3 Java语法
- ehcache
- google地图的调用
- Linux——I/O复用
- zoj 1338 || poj 1492 Up and Down Sequences
- DataGridView控件导出到Excel文件
- JQ 图片滚动
- linux font
- char* pFindStr(char* sStr,char* sDest)
- 如何建立simuation环境
- joj 1026解题报告
- The outline: Oracle Database 11g: Performance Tuning DBA Release 2