您的位置:首页 > 其它

多路复用IO&select&poll

2017-06-01 18:06 603 查看

概述

Linux提供了两个函数来实现多路复用IO操作

正文

函数select

函数原型

int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);

void FD_CLR(int fd, fd_set *set);

int FD_ISSET(int fd, fd_set *set);

void FD_SET(int fd, fd_set *set);

void FD_ZERO(fd_set *set);

参数

参数ndfs:select中监视的文件句柄数,一般设为要监视的文件中的最大fd+1。

参数readfds:需要读取的fd_set类型的结构体地址

参数writefds: 需要写入的fd_set类型的结构体地址

参数exceptfds:

参数timeout:select()的超时结束时间。

这个参数它使select处于三种状态,

第一,若将NULL以形参传入,即不传入时间结构,就是将select置于阻塞状态,

一定等到监视文件描述符集合中某个文件描述符发生变化为止;

第二,若将时间值设为0秒0毫秒,就变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,

都立刻返回继续执行,文件无变化返回0,有变化返回一个正值;

第三,timeout的值大于0,这就是等待的超时时间,即select在timeout时间内阻塞,

超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回,返回值同上述。

返回值

返回值:

负值:select错误

0:等待超时,没有可读写或错误的文件

正值:某些文件可读可写或出错

测试代码

int main(int argc,char **argv)
{
int fd = -1,ret = -1;
char buf[100] = {0};
fd_set Myreadfds;
struct timeval  Mytimeout;

fd = open(MOUSE,O_RDONLY );/*鼠标阻塞*/
if(fd<0)
{
perror("open ");
return -1;
}

/*fd -> mouse, 0->keyboard*/
FD_ZERO(&Myreadfds);/*清空内容*/
FD_SET(fd,&Myreadfds);/*添加fd*/
FD_SET(0,&Myreadfds);/*添加fd*/
Mytimeout.tv_sec = 3;/*设置超时时间*/
Mytimeout.tv_usec = 0;
ret = select(fd+1,&Myreadfds,NULL,NULL,&Mytimeout);
if(ret<0)
{
perror("select ");
return -1;
}
else if(ret == 0)
printf("time out.\r\n");
else
{
if(FD_ISSET(0,&Myreadfds))/*keyboard*/
{
memset(buf,0,sizeof(buf));
ret = read(0,buf,100);  /*读取标准输入的值*/
if(ret>0)
printf("keyboard[%d] = %s\r\n",ret,buf);
}
else if(FD_ISSET(fd,&Myreadfds))/*mouse*/
{
memset(buf,0,sizeof(buf));
ret = read(fd,buf,100);/*读取鼠标的值*/
if(ret>0)
printf("mouse[%d] = %s\r\n",ret,buf);
}
}

close(fd);
return 0;
}


函数poll

函数原型

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

参数

参数fds为需要操作的struct pollfd 类型的结构体的地址

参数ndfs:select中监视的文件句柄数,一般设为要监视的文件中的最大fd+1。

参数timeout为最大超时时间(单位ms)

返回值

负值:poll错误

0:等待超时,没有可读写或错误的文件

正值:成功

测试代码

int main(int argc,char **argv)
{
int fd = -1,ret = -1;
char buf[100] = {0};
struct pollfd Myfds[2] = {0};

fd = open(MOUSE,O_RDONLY );/*鼠标阻塞*/
if(fd<0)
{
perror("open ");
return -1;
}

Myfds[0].fd = 0;/*keyboard*/
Myfds[0].events = POLLIN;/*输入方式*/

Myfds[1].fd = fd;/*mouse*/
Myfds[1].events = POLLIN;/*输入方式*/
ret = poll(Myfds,fd+1,3000);/*超时3s*/
if(ret<0)
{
perror("select ");
return -1;
}
else if(ret == 0)
printf("time out.\r\n");
else
{
if(Myfds[0].events == Myfds[0].revents)//keyboard
{
memset(buf,0,sizeof(buf));
ret = read(0,buf,100);  /*读取标准输入的值*/
if(ret>0)
printf("keyboard[%d] = %s\r\n",ret,buf);
}
else if(Myfds[1].events == Myfds[1].revents)//mouse
{
memset(buf,0,sizeof(buf));
ret = read(fd,buf,100);/*读取鼠标的值*/
if(ret>0)
printf("mouse[%d] = %s\r\n",ret,buf);
}
}
close(fd);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: