I/O多路转接之poll
与select使用三个位图来表示三个fdset的方式不同,poll使用一个pollfd的指针来实现。
poll解决了select两个重要的问题:
(1)poll服务器在处理文件描述符个数上理论上无上限;
(2)poll服务器将输入参数与输出参数进行分离,不用每次使用时进行重新设置。
函数形式:
int poll(struct pollfd *fds,nfds_t nfds,int timeout);
struct pollfd
{
int fd;
short event;
short revents; //作为返回值,将文件描述符上的就绪事件写入revents,不用每次检测。
}
{
int fd;
short event;
short revents; //作为返回值,将文件描述符上的就绪事件写入revents,不用每次检测。
}
实现一个mypoll
当timeout=-1时,一直处于阻塞状态
#include
#include
int main()
{
struct pollfd fds;
fds.fd=0;
fds.events=POLLIN;
fds.revents=0;
int timeout=500;
while(1)
{
switch(poll(&fds,1,timeout))
{
case 0:
printf("timeout...\n");
break;
case -1:
perror("mypoll");
break;
default:
{
char buf[1024];
//at least one ev ready!
if(fds.revents & POLLIN)
{
ssize_t s=read(fds.fd,buf,sizeof(buf));
if(s>0)
{
buf[s]=0;
printf("echo# %s\n",buf);
}
}
}
break;
}
}
}
运行结果:
当timeout=0时,缓冲池瞬间被写满
#include
#include
int main()
{
struct pollfd fds;
fds.fd=0;
fds.events=POLLIN;
fds.revents=0;
int timeout=500;
while(1)
{
switch(poll(&fds,1,timeout))
{
case 0:
printf("timeout...\n");
break;
case -1:
perror("mypoll");
break;
default:
{
char buf[1024];
//at least one ev ready!
if(fds.revents & POLLIN)
{
ssize_t s=read(fds.fd,buf,sizeof(buf));
if(s>0)
{
buf[s]=0;
printf("echo# %s\n",buf);
}
}
}
break;
}
}
}
运行结果:
当timeout=500时,表示每隔500毫秒写一次