- 青岛雅思—专家谈雅思考试发展趋势
- 河南2011上半年自考网上报名入口 点击进入
- 2011年广东省护士资格考试报名现场确认时间
- 2011上半年乐山五通桥区会计从业考试报名3月10日-4月1
- 哈尔滨香坊区2011护士资格考试报名现场确认时间
- 2011什邡第一次会计从业资格考试报名3月1日-4月15日
- 2011什邡第二次会计从业资格考试报名7月1日-9月16日
- 2011年中山市护士资格考试报名工作的通知
- 长安大学2011考研成绩查询入口 点击进入
- 西华大学2011考研成绩查询入口 点击进入
- 中国地质大学(武汉)2011考研成绩3月3日查询
- 中南民族大学2011考研成绩查询3月4日开始
- 沈阳建筑大学2011考研成绩查询入口 点击进入
- 沈阳工业大学2011考研成绩查询入口 点击进入
【武汉华嵌】poll和select的使用和差异
来源:求学问校网 发表时间:2011-10-26 浏览 68 次
作者:武汉华嵌技术部
使用非阻塞I/O 的应用程序常常使用poll, select。poll和select本质上有相同的功能:每个允许一个进程来决定它是否可读或者写一个或多个文件而不阻塞。这些调用也可阻塞进程直到任何一个给定集合的文件描述符可用来读或写。因此,它们常常用在必须使用多输入输出流的应用程序,而不必粘连在它们任何一个上. 相同的功能常常由多个函数提供,因为2 个是由不同的团队在几乎相同时间完成的:select 在BSD Unix 中引入,而poll 是System V 的解决方案。
那么以下分别来分析下select和poll的各自用法。
首先来分析下select:
1、函数原型如下:
#include <sys/select.h>
int select(int maxfdp1, fd_set *restrict readfds,
fd_set *restrict writefds, fd_set *restrict exceptfds,
struct timeval *restrict tvptr);
2、select做了些什么?分两次来讲:
⑴、传向select的参数告知内核,我们所关心的描述符;对于每个描述符我们所关心的状态;愿意等待多长时间。
⑵、select返回时,内核告诉我们已经准备好的描述符的数量;对于读、写或异常这三个状态中的每一个,哪里些描述符已经准备好。
3、select函数参数分析:
⑴最后一个参数,它指定愿意等待的时间。
struct timeval{
long tv_sec; //seconds
long tv_usec; //and microseconds
};
tvptr == NULL时,永远等待。
tvptr->tv_sec == 0 && tvptr->tv_usec == 0时,完全不等待。
tvptr->tv_sec != 0 || tvptr->tv_usec != 0时,等待指定的秒数和微秒数。
⑵、中间的三个参数readfds、writefds、exceptfds是指向描述符集的指针。这三个参数描述符集说明了我们关心的可读、可写或处于异常条件的各个描述符。每个描述符集存放在一个fd_set数据类型中。这各数据类型为每一可能的描述符保持了一个bit位。
对fd_set数据类型可以进行的处理是:分配一个这种类型的变量;将这种类型的一个变量值赋予同类型的另一个变量;或对于这种类型的变量使用下列四个函数中的一个。
#include <sys/select.h>
int FD_ISSET(int fd, fd_set *fdset);
返回值:若fd在描述符集中则返回非0值,否则返回0。
void FD_CLR(int fd, fd_set *fdset);
void FD_SET(int fd, fd_set *fdset);
void FD_ZERO(fd_set *fdset);
以上这些接口的作用分别是:FD_ZERO将一个指定的fd_set变量的所有位设置为0。FD_SET设置一个fd_set变量的指定位。FD_CLR将一指定位清除。FD_ISSET测试一指定位是否设置。
这三个参数中的任意一个或全部都可以是空指针,这表示对相应状态并不关心。如果所有三个指针都是空指针,则select提供了较sleep更精确的计时器。
⑶、第一个参数maxfdp1的意思是“最大描述符加1”。在三个描述符集中找到最大描述符编号值,然后加1,这就是第一个参数。
4、select返回值分析:
⑴、返回-1,表示出错。
⑵、返回0,表示没有描述符准备好。若指定的描述符都没有准备好,而且指定的时间已经超过,则发生这种情况。此时,所有描述符集皆被清0。
⑶、正返回值表示已经准备好的描述符数,该值是三个描述符集中已经准备好的描述符数之和,所以如果同一描述符已经准备好读和写,那么在返回值班中将其计为2.在这种情况下,三个描述符集中仍旧打开的位对应于已经准备好的描述符。
5、select使用的片段代码如下:
fd_set inset, tmp_inset;//声名两个描述符集
FD_ZERO(&inset);//清0
FD_SET(sockfd, &inset);//设置sockfd的指定位
if (!(select(MAX_SOCK_FD, &tmp_inset, NULL, NULL, NULL) > 0))
//在这里等着,等到描述符集中的任何一个描述符有反应了,就返回、、//正值
{
perror("select");
close(sockfd);
exit(1);
}
分析完select,现在分析下poll:
函数原型如下:
#include <poll.h>
int poll(struct pollfd fdarray[], nfds_t nfds, int timeout);
poll函数参数分析:
⑴最后一个参数,它指定愿意等待的时间。
timeout == -1时,永远等待。
timeout == 0时,不等待。
timeout > 0时,等待timeout毫秒。(如果系统不提供望毫秒分辨,则timeout值取整到最近的支持值)
⑵与select不同,poll不是为每个状态构造一个描述符集,面是构造一个pollfd结构数组,每个数组元素指定一个描述符编号以及对其所关心的状态。pollfd结构如下:
struct pollfd{
int fd; //file descriptor to check, or < 0 to ignore
short events; //events of interest on fd
short revents;//events that occurred on fd
};
应将每个数组元素的events成员设置如下表的值。通过这些值告诉内核我们对该描述符关心的产什么。返回时,内核设置revents成员,以说明对于该描述符已经发生了什么事件。
标志名
输入至
events?
从revents得到结果?
说明
POLLIN
Yes
Yes
不阻塞地可读除高优先级外的数据
POLLRDNORM
Yes
Yes
不阻塞地可读普通数据
POLLRDBAND
Yes
Yes
不阻塞地可读非0优先级波段数据
POLLPRI
Yes
Yes
不阻塞地可读高优先级数据
POLLOUT
Yes
Yes
不阻塞地可写普通数据
POLLWRNORM
Yes
Yes
与POLLOUT相同
POLLWRBAND
Yes
Yes
不阻塞的可写非0优先级波段数据
POLLERR
Yes
已出错
POLLHUP
Yes
已挂断
POLLNVAL
Yes
描述符不引用一打开文件
⑶nfds说明fdarray数组中的元素数。
poll返回值分析:
⑴、返回0时,超时返回。
⑵、返回-1时,出错返回。
⑶、返回正值时,表示准备就绪的描述符数。
poll使用的片段代码如下:
struct pollfd pollfds[1]; //声明一个struct pollfd结构数组
pollfds[0].fd = fd ; //初始化struct pollfd数组第0个元素成员
pollfds[0].events = POLLIN;//初始化对该描述符所关心的
while (!terminate) {
if (poll(pollfds, 1, 100) <= 0)/*正常返回,得到的是准备就绪的描述符数。如果时间到了还没有描述符有反应,那么就返回-1,结束本次循环。*/
continue;
……………
……………
}
注意:
执行select后,如果成功了,其改变了描述符集中的内容,也就让没有反应的描述符位清0。而poll在执行结束后,并没有改变events中的内容,而是把执行的事件设置给revents来告知客户。
使用非阻塞I/O 的应用程序常常使用poll, select。poll和select本质上有相同的功能:每个允许一个进程来决定它是否可读或者写一个或多个文件而不阻塞。这些调用也可阻塞进程直到任何一个给定集合的文件描述符可用来读或写。因此,它们常常用在必须使用多输入输出流的应用程序,而不必粘连在它们任何一个上. 相同的功能常常由多个函数提供,因为2 个是由不同的团队在几乎相同时间完成的:select 在BSD Unix 中引入,而poll 是System V 的解决方案。
那么以下分别来分析下select和poll的各自用法。
首先来分析下select:
1、函数原型如下:
#include <sys/select.h>
int select(int maxfdp1, fd_set *restrict readfds,
fd_set *restrict writefds, fd_set *restrict exceptfds,
struct timeval *restrict tvptr);
2、select做了些什么?分两次来讲:
⑴、传向select的参数告知内核,我们所关心的描述符;对于每个描述符我们所关心的状态;愿意等待多长时间。
⑵、select返回时,内核告诉我们已经准备好的描述符的数量;对于读、写或异常这三个状态中的每一个,哪里些描述符已经准备好。
3、select函数参数分析:
⑴最后一个参数,它指定愿意等待的时间。
struct timeval{
long tv_sec; //seconds
long tv_usec; //and microseconds
};
tvptr == NULL时,永远等待。
tvptr->tv_sec == 0 && tvptr->tv_usec == 0时,完全不等待。
tvptr->tv_sec != 0 || tvptr->tv_usec != 0时,等待指定的秒数和微秒数。
⑵、中间的三个参数readfds、writefds、exceptfds是指向描述符集的指针。这三个参数描述符集说明了我们关心的可读、可写或处于异常条件的各个描述符。每个描述符集存放在一个fd_set数据类型中。这各数据类型为每一可能的描述符保持了一个bit位。
对fd_set数据类型可以进行的处理是:分配一个这种类型的变量;将这种类型的一个变量值赋予同类型的另一个变量;或对于这种类型的变量使用下列四个函数中的一个。
#include <sys/select.h>
int FD_ISSET(int fd, fd_set *fdset);
返回值:若fd在描述符集中则返回非0值,否则返回0。
void FD_CLR(int fd, fd_set *fdset);
void FD_SET(int fd, fd_set *fdset);
void FD_ZERO(fd_set *fdset);
以上这些接口的作用分别是:FD_ZERO将一个指定的fd_set变量的所有位设置为0。FD_SET设置一个fd_set变量的指定位。FD_CLR将一指定位清除。FD_ISSET测试一指定位是否设置。
这三个参数中的任意一个或全部都可以是空指针,这表示对相应状态并不关心。如果所有三个指针都是空指针,则select提供了较sleep更精确的计时器。
⑶、第一个参数maxfdp1的意思是“最大描述符加1”。在三个描述符集中找到最大描述符编号值,然后加1,这就是第一个参数。
4、select返回值分析:
⑴、返回-1,表示出错。
⑵、返回0,表示没有描述符准备好。若指定的描述符都没有准备好,而且指定的时间已经超过,则发生这种情况。此时,所有描述符集皆被清0。
⑶、正返回值表示已经准备好的描述符数,该值是三个描述符集中已经准备好的描述符数之和,所以如果同一描述符已经准备好读和写,那么在返回值班中将其计为2.在这种情况下,三个描述符集中仍旧打开的位对应于已经准备好的描述符。
5、select使用的片段代码如下:
fd_set inset, tmp_inset;//声名两个描述符集
FD_ZERO(&inset);//清0
FD_SET(sockfd, &inset);//设置sockfd的指定位
if (!(select(MAX_SOCK_FD, &tmp_inset, NULL, NULL, NULL) > 0))
//在这里等着,等到描述符集中的任何一个描述符有反应了,就返回、、//正值
{
perror("select");
close(sockfd);
exit(1);
}
分析完select,现在分析下poll:
函数原型如下:
#include <poll.h>
int poll(struct pollfd fdarray[], nfds_t nfds, int timeout);
poll函数参数分析:
⑴最后一个参数,它指定愿意等待的时间。
timeout == -1时,永远等待。
timeout == 0时,不等待。
timeout > 0时,等待timeout毫秒。(如果系统不提供望毫秒分辨,则timeout值取整到最近的支持值)
⑵与select不同,poll不是为每个状态构造一个描述符集,面是构造一个pollfd结构数组,每个数组元素指定一个描述符编号以及对其所关心的状态。pollfd结构如下:
struct pollfd{
int fd; //file descriptor to check, or < 0 to ignore
short events; //events of interest on fd
short revents;//events that occurred on fd
};
应将每个数组元素的events成员设置如下表的值。通过这些值告诉内核我们对该描述符关心的产什么。返回时,内核设置revents成员,以说明对于该描述符已经发生了什么事件。
标志名
输入至
events?
从revents得到结果?
说明
POLLIN
Yes
Yes
不阻塞地可读除高优先级外的数据
POLLRDNORM
Yes
Yes
不阻塞地可读普通数据
POLLRDBAND
Yes
Yes
不阻塞地可读非0优先级波段数据
POLLPRI
Yes
Yes
不阻塞地可读高优先级数据
POLLOUT
Yes
Yes
不阻塞地可写普通数据
POLLWRNORM
Yes
Yes
与POLLOUT相同
POLLWRBAND
Yes
Yes
不阻塞的可写非0优先级波段数据
POLLERR
Yes
已出错
POLLHUP
Yes
已挂断
POLLNVAL
Yes
描述符不引用一打开文件
⑶nfds说明fdarray数组中的元素数。
poll返回值分析:
⑴、返回0时,超时返回。
⑵、返回-1时,出错返回。
⑶、返回正值时,表示准备就绪的描述符数。
poll使用的片段代码如下:
struct pollfd pollfds[1]; //声明一个struct pollfd结构数组
pollfds[0].fd = fd ; //初始化struct pollfd数组第0个元素成员
pollfds[0].events = POLLIN;//初始化对该描述符所关心的
while (!terminate) {
if (poll(pollfds, 1, 100) <= 0)/*正常返回,得到的是准备就绪的描述符数。如果时间到了还没有描述符有反应,那么就返回-1,结束本次循环。*/
continue;
……………
……………
}
注意:
执行select后,如果成功了,其改变了描述符集中的内容,也就让没有反应的描述符位清0。而poll在执行结束后,并没有改变events中的内容,而是把执行的事件设置给revents来告知客户。
武汉电脑培训培训相关新闻
武汉电脑培训相关课程
- 暑假武汉网页设计培训班、武汉网页设计全能班培训、武汉网站优化…
- 武汉网页设计全能班培训、武汉网页设计培训班、武汉网站优化培训…
- 武汉网页设计培训班、武汉网页设计全能班培训、武汉网站优化培训…
- 武汉网页设计美工培训、武汉网页设计师培训、武汉平面设计培训、…
- 武汉网页短期速成班培训、武汉网站优化培训、武汉网页全科班、武…
- 武昌武汉办公基础培训、武汉办公精品班培训、武昌办公文秘培训、…
- 武汉办公文员培训、武汉计算机短期培训、武昌办公软件培训学校、…
- 武汉办公自动化培训学校、武昌办公文秘培训、武昌计算机基础培训…
- 武汉高级办公文秘培训、武昌高级商务文秘班、武昌办公基础培训、…
- 武汉计算机短期培训、武昌办公软件培训学校、武昌高级办公软件培…
- 武汉平面设计短期培训、武汉平面设计培训、武汉平面广告设计培训…
- 武汉ps高级培训班、武汉平面设计培训、武汉平面广告设计培训、武…
- 武汉ps短期培训、武昌ps培训、武汉平面设计培训、武汉平面广告设…
- 武汉平面广告高级班、武汉平面设计培训、武汉平面广告设计培训、…