I/O多路复用

I/O多路复用

参考链接:

select() 系统调用

select()系统调用可以使进程检测同时等待的多个I/O设备,网站空间,当没有设备准备好时,select()阻塞,其中任一设备准备好时,select()就返回。

#include <sys/select.h>#include <sys/time.h>*readfds, fd_set *writefds, fd_set *exceptfds, const struct timeval *timeout);

select的第一个参数是文件描述符集中要被检测的比特数,这个值必须至少比待检测的最大文件描述符大1;参数readfds指定了被读监控的文件描述符集;参数writefds指定了被写监控的文件描述符集;而参数exceptfds指定了被例外条件监控的文件描述符集。参数timeout起了定时器的作用:到了指定的时间,无论是否有设备准备好,都返回调用。

timeval的结构定义如下:struct timeval{ long tv_sec; //表示几秒 long tv_usec; //表示几微妙}

timeout取不同的值,该调用就表现不同的性质:

1.timeout为0,调用立即返回;2.timeout为NULL,虚拟主机,select()调用就阻塞,直到知道有文件描述符就绪;3.timeout为正整数,就是一般的定时器。

select调用返回时,除了那些已经就绪的描述符外,select将清除readfds、writefds和exceptfds中的所有没有就绪的描述符。select的返回值有如下情况: 1.正常情况下返回就绪的文件描述符个数;2.经过了timeout时长后仍无设备准备好,网站空间,返回值为0;3.如果select被某个信号中断,它将返回-1并设置errno为EINTR。4.如果出错,返回-1并设置相应的errno。

系统提供了4个宏对描述符集进行操作:

#include <sys/select.h>#include <sys/time.h> void FD_SET(int fd, fd_set *fdset); void FD_CLR(int fd, fd_set *fdset); void FD_ISSET(int fd, fd_set *fdset); void FD_ZERO(fd_set *fdset);

宏FD_SET设置文件描述符集fdset中对应于文件描述符fd的位(设置为1),宏FD_CLR清除文件描述符集 fdset中对应于文件描述符fd的位(设置为0),宏FD_ZERO清除文件描述符集fdset中的所有位(既把所有位都设置为0)。使用这3个宏在调用select前设置描述符屏蔽位,在调用select后使用FD_ISSET来检测文件描述符集fdset中对应于文件描述符fd的位是否被设置。

select的使用方法:

1. 将要监控的文件添加到文件描述符集2. 调用select开始监控3. 判断文件是否发生变化。

FD_ZERO(&fds); //清空集合FD_SET(fd1,&fds); //设置描述符FD_SET(fd2,&fds); //设置描述符maxfdp=fd1+1; //描述符最大值加1,假设fd1>fd2switch(select(maxfdp,&fds,NULL,NULL,&timeout))case -1: exit(-1);break; //select错误,退出程序case 0:break;default:if(FD_ISSET(fd1,&fds))…. //测试fd1是否可读

可运行源代码:

#include<sys/time.h>#include<sys/types.h>#include <unistd.h>#include<stdio.h>#include<unistd.h>#include<fcntl.h>#include<stdlib.h>#define TIMEOUT 5#define BUF_LEN 1024int max(int a,int b){return (a>b)?a:b;}int main(void){struct timeval tv;fd_set readfds;int fd_open, fd ,maxfdp1;int ret;fd_open = open(,O_RDONLY);FD_ZERO(&readfds);FD_SET(STDIN_FILENO, &readfds);FD_SET(fd_open, &readfds);tv.tv_sec = TIMEOUT;tv.tv_usec = 0;maxfdp1 = max(STDIN_FILENO , fd_open) + 1;ret = select(maxfdp1,&readfds,NULL,NULL, &tv);if(ret == -1){perror();return 1;}else if(!ret){printf(,TIMEOUT);return 0;}if (FD_ISSET(STDIN_FILENO, &readfds)){char buf[BUF_LEN+1];int len;len = read(STDIN_FILENO,buf,BUF_LEN);if(len == -1){perror();}if(len){buf[len] = ;printf(,buf);}}if (FD_ISSET(fd_open, &readfds)){char buf[BUF_LEN+1];int len;len = read(fd_open,buf,BUF_LEN);if(len == -1){perror();}if(len){buf[len] = ;printf(,buf);}}fprintf(stderr,);return 1;}

GCC编译通过,可以自行测试运行,本程序测试了两个描述符,一个标准输入,一个是文件描述符。

posted on

我不去想是否能够成功,既然选择了远方,便只顾风雨兼程!

I/O多路复用

相关文章:

你感兴趣的文章:

标签云: