问题:1. 采用管道函数创建有名管道,使用select函数替代使用poll函数实现多路复用:创建两个有名管道,获取3个文件描述符(2个管道1个标准输入),然后初始化读文件描述符,select监视文件描述符的文件读写,管道1输出到屏幕上,管道2输出到屏幕上,标准输入‘Q’来进行判读是否退出
原型int select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
参数:
nfds:select()函数监视的描述符数的最大值,一般取监视的描述符数的最大值+1,
其上限设置在sys/types.h中有定义
#define FD_SETSIZE 256
readfds:select()函数监视的可读描述符集合
wtitefds:select()函数监视的可写描述符集合
errnofds:select()函数监视的异常描述符集合
timeout:结构timeval,用来设置等待事件,select()函数监视超时结束时间,取NULL表示永久等待
timeval结构定义如下
struct timeval
{
time_t tv_sec;
time_t tv_usec;
};
返回值:返回总的位数这些位对应已准备好的描述符,否则返回-1
相关宏操作:
select()函数实现IO多路复用的步骤
(1)清空描述符集合
(2)建立需要监视的描述符与描述符集合的关系
(3)调用select函数
(4)检查监视的描述符判断是否已经准备好
(5)对已经准备好的描述符进程IO操作
问题设计流程
代码:
#include
#include
#include
#include
#include
#include
#include
#define FIFO1 "in1" #define FIFO2 "in2" #define MAX_BUFFER_SIZE 1024 //缓冲区大小 #define IN_FILES 3 //多路复用输入文件数目 #define TIME_DELAY 60 //超时值秒数 #define MAX(a,b) ((a>b)?(a):(b)) int main(void) { int fds[IN_FILES]; //管道描述符 char buf[MAX_BUFFER_SIZE]; int i,res,real_read,maxfd; struct timeval tv; fd_set inset,tmp_inset;//文件描述符集 fds[0]=0; //终端的文件描述符 /*创建两个有名管道*/ if(access(FIFO1,F_OK)==-1) { if((mkfifo(FIFO1,0666)<0)&&(errno!=EEXIST)) { printf("Cannot create fifo1 file\n"); exit(1); } } if(access(FIFO2,F_OK)==-1) { if((mkfifo(FIFO2,0666)<0)&&(errno!=EEXIST)) { printf("Cannot create fifo2 file\n"); exit(1); } } /*以只读非阻塞方式打开两个管道文件*/ if((fds[1]=open(FIFO1,O_RDONLY|O_NONBLOCK))<0) { printf("Open in1 error\n"); return 1; } if((fds[2]=open(FIFO2,O_RDONLY|O_NONBLOCK))<0) { printf("Open in2 error\n"); return 1; } /*取出两个文件描述符中的较大者*/ maxfd=MAX(MAX(fds[0],fds[1]),fds[2]); /*初始化读集inset,并在读文件描述符集中加入相应的描述集*/ FD_ZERO(&inset); /*将inset清零,使集合中不含任何fd*/ for(i=0;i