select,pselect,poll函数
来源:互联网 发布:惠普m1213nf mac驱动 编辑:程序博客网 时间:2024/05/08 02:26
select
机制:
select实现了一种I/O复用,允许多个套接口阻塞在一个select函数上,而不是阻塞在I/O上,当在套接口集中,有一个及其以上的描述字有效时候,就会返回,这样对于阻塞在一个描述字上来说,提高了效率.
select函数
#include <sys/select.h>
#include <sys/time.h>
int select(int maxfdp1, fd_set *read_set,fd_set *write_set,
fd_set *exceptset,const struct timeval *timeout);
功能:
#include <sys/select.h>
#include <sys/time.h>
int select(int maxfdp1, fd_set *read_set,fd_set *write_set,
fd_set *exceptset,const struct timeval *timeout);
功能:
该函数允许进程等待多个描述字,当有一个或多个描述字准备好或超时的时候返回.每次返回时都要清空描述字,所以每次使用select前都要重新设置.
参数:
maxfdp1: 是集合中描述字的范围,即:允许等待的最大的描述字的值+1,通常为1024
fd_set:一般指定内核测试可读可写还是异常.
struct timeval {
long tv_sec; //second
long tv_sec; //microsecods
};
设置等待时间:
1.设置为空指针:永远等下去,直到至少有一个描述字准备好.
2.等待一段固定的时间.分别指定秒和微秒(精度没有这么高,一般为10ms的整数倍).
3.不等待,即轮询,因此必须指向一个timeval结构,且其值必须为0
理解select的关键在于fd_set,对于fd_set,我们有四个函数进行设置:
#include <sys/select.h>
void FD_ZERO(fd_set *fdset); //对fd_set清零
void FD_SET(int fd,fd_set *fdset);//设置对应描述字的位置为1
void FD_CLR(int fd ,fd_set *fdset); //关闭对应描述字的位
void FD_ISSET(int fd, fd_set *fd_set); //检测相应描述字是否有效
例子:
fd_set fdset;
FD_ZERO(&fdset);//清零
FD_SET(fd,&fdset);//设置对应描述字有效
select(maxfd,fdset,null,null,&timeout);//调用select,检测描述字是否可读,否则在指定时间后返回.
当fd_set类型的三个参数都为NULL的时候,这是一个精准的定时器.
fd_set类型是一个数组,这个数组总每一个数组的每一个位都标志着唯一一个描述字,无论你是否使用,若使用则该位置设为1.
缺陷:
1.描述字的范围是有限的,最多仅可以监控0-1024;
2.效率很低,select是线性扫描描述字
3.select采用内核拷贝的方法,把内核描述字的消息通知给用户空间
参数:
maxfdp1: 是集合中描述字的范围,即:允许等待的最大的描述字的值+1,通常为1024
fd_set:一般指定内核测试可读可写还是异常.
struct timeval {
long tv_sec; //second
long tv_sec; //microsecods
};
设置等待时间:
1.设置为空指针:永远等下去,直到至少有一个描述字准备好.
2.等待一段固定的时间.分别指定秒和微秒(精度没有这么高,一般为10ms的整数倍).
3.不等待,即轮询,因此必须指向一个timeval结构,且其值必须为0
理解select的关键在于fd_set,对于fd_set,我们有四个函数进行设置:
#include <sys/select.h>
void FD_ZERO(fd_set *fdset); //对fd_set清零
void FD_SET(int fd,fd_set *fdset);//设置对应描述字的位置为1
void FD_CLR(int fd ,fd_set *fdset); //关闭对应描述字的位
void FD_ISSET(int fd, fd_set *fd_set); //检测相应描述字是否有效
例子:
fd_set fdset;
FD_ZERO(&fdset);//清零
FD_SET(fd,&fdset);//设置对应描述字有效
select(maxfd,fdset,null,null,&timeout);//调用select,检测描述字是否可读,否则在指定时间后返回.
当fd_set类型的三个参数都为NULL的时候,这是一个精准的定时器.
fd_set类型是一个数组,这个数组总每一个数组的每一个位都标志着唯一一个描述字,无论你是否使用,若使用则该位置设为1.
缺陷:
1.描述字的范围是有限的,最多仅可以监控0-1024;
2.效率很低,select是线性扫描描述字
3.select采用内核拷贝的方法,把内核描述字的消息通知给用户空间
效率低的原因:
1.每次把描述字从用户空间拷贝到内核空间,等待select结束时再把描述字从内核空间拷贝到用户空间.
2.select是线性扫描0-maxfd范围内的描述字,而且是周期性扫描(扫描一遍后睡眠,等待内核定时器到时进行下一次扫描),直到有描述字准备好或者到时为止.
说了半天还不如来张图:
我们假设fd_set是一个整数数组组成的标志fd的结构,那么如图:
以下条件满足之一时候,读准备好:
1.套接口接收缓冲区的数据字节数大于低潮标记,不阻塞,并返回大于0的数,即准备好读的套接口.
2.套接口读的这一半关闭,即接受了FIN标记的tcp连接,这样的套接口不阻塞并返回0,即EOF.
3.套接口为一个监听端口且已创建的连接数不为0,对于这样的套接口的accept通常不会阻塞
4.套接口发生了一个错误,这样的套接口不阻塞并返回-1,设置errno为错误类型
以下条件之一满足则写准备好
1.套接口发送缓冲区的可用空间字节数大于低潮标记,不阻塞,返回可写套接口数
2.套接口写的这一半关闭,对于这样的套接口写操作将产生一个SIGPIPE信号.
3.套接口早先使用飞阻塞connect,并且连接已经异步建立.或者connect以失败告终.
3.套接口中有一个错误.
1.套接口接收缓冲区的数据字节数大于低潮标记,不阻塞,并返回大于0的数,即准备好读的套接口.
2.套接口读的这一半关闭,即接受了FIN标记的tcp连接,这样的套接口不阻塞并返回0,即EOF.
3.套接口为一个监听端口且已创建的连接数不为0,对于这样的套接口的accept通常不会阻塞
4.套接口发生了一个错误,这样的套接口不阻塞并返回-1,设置errno为错误类型
以下条件之一满足则写准备好
1.套接口发送缓冲区的可用空间字节数大于低潮标记,不阻塞,返回可写套接口数
2.套接口写的这一半关闭,对于这样的套接口写操作将产生一个SIGPIPE信号.
3.套接口早先使用飞阻塞connect,并且连接已经异步建立.或者connect以失败告终.
3.套接口中有一个错误.
pselect:
机制:
同select
pselect函数:
#include <sys/select.h>#include <signal.h>
#include <time.h>
int pselect(int maxfdp1, fd_set *read_set,fd_set *write_set,
fd_set *exceptset,const struct timespec *timeout, const sigset_t *sigmask);
参数:
timespec:精确到纳秒
struct timespec {
time_t tv_sec;
long tv_nsec; //纳秒
};
sigset_t: 指向信号掩码的指针.用于阻塞信号的.
注释:
1.在进程阻塞于select期间,如果有信号发生则select返回errno(EINTR),如果不想select被打断则使用pselect,并指定我们想阻塞的信号,等到pselect返回时候再恢复信号.
2.pselect在效率上和select毫无差别
使用:
sigset_t zeromask;
sigemptyset(&zeromask); //清空
sigaddset(&zeromask,SIGINT);//设置要阻塞的信号,即初始化
pselect(.....,&zeromask);
sigset_t zeromask;
sigemptyset(&zeromask); //清空
sigaddset(&zeromask,SIGINT);//设置要阻塞的信号,即初始化
pselect(.....,&zeromask);
poll
机制:
同上.
poll函数:
#include <poll.h>
int poll(struct pollfd *fdarray,unsigned long nfds,int timeout);
#include <poll.h>
int poll(struct pollfd *fdarray,unsigned long nfds,int timeout);
参数:
struct pollfd {
int fd; //关心的描述字
short events; //描述字上待测试的事件
short revents; //描述字上发生的事件
}
nfds: fdarray的长度.
timeout:毫秒,实际上精度为10ms
注释:
1.该函数定义了一个pollfd结构数组,传入关心的描述字个数不受限制(无上限)
2.该函数不像select一样每次执行完毕后将描述字清零,poll只需要设置一次pollfd数组,除非对感兴趣的描述字发生了变化.
3.该函数效率依旧不高,依然进行线性扫描.
4.每次进行内核空间和用户空间的数据拷贝,浪费时间和空间.
5.poll是水平触发,即只要缓冲区还有数据就会返回.
0 0
- select,pselect,poll函数
- select pselect poll
- 关于select , pselect , poll
- linux select pselect poll 异同
- select pselect poll ppoll epoll
- select、pselect、poll和epoll的区别
- I/O复用:select、poll、pselect和epoll
- select 和 pselect 函数使用的分析
- Linux网络编程--select()和pselect()函数
- select和poll函数
- select/poll 函数
- select,poll,epoll函数
- UNIX环境高级编程——I/O多路转接(select、pselect和poll)
- I/O多路转接(select、pselect和poll)使用
- I/O复用(I/O multiplexing): select, pselect, poll, ppoll, epoll
- UNIX编程专题-I/O复用:select、pselect、poll和epoll解析
- select()与pselect()
- select() vs pselect()
- 山东理工大学ACM平台题答案关于C语言 1177 C语言实验——时间间隔
- Cocos2d-x 菜单的响应
- Main Steps of Antenna Analysis with HFSS
- POJ 1013 Counterfeit Dollar 解题报告
- 三种不同类型的ssh隧道
- select,pselect,poll函数
- 论研发团队的演化--超宏观篇--续
- PycURL 网络编程
- Ubuntu 编译安装 hadoop 2.2.0
- 即时到帐中如何实现分润功能?
- struts2系列十之4中获取使用request,session,application的方法和页面显示的三种方法【后期ognl算第四种】
- jquery-Validation 的使用方法
- uva424Integer Inquiry
- 数据包接受完整流程