3.3 方法3:多路复用IO解决阻塞问题
head.h
1 //方法3:多路复用IO解决阻塞问题 2 #ifndef _HEAD_H_ 3 #define _HEAD_H_ 4 #include <stdio.h> 5 #include<stdlib.h> 6 #include<string.h> 7 #include<error.h> 8 #include<errno.h> 9 #include<sys/types.h> 10 #include<sys/socket.h> 11 #include<netinet/in.h> 12 #include<netinet/ip.h> 13 #include<arpa/inet.h> 14 #include<signal.h> 15 #include<sys/stat.h> 16 #include<fcntl.h> 17 #include<sys/select.h> 18 19 #define error_exit(_errmsg_) error(EXIT_FAILURE,errno,_errmsg_) 20 #endif
Makefile
1 ALL:r w 2 r:read.c 3 gcc $< -o $@ 4 w:write.c 5 gcc $< -o $@ 6 .PHONY: 7 clean: 8 rm r w
write.c
1 #include"head.h" 2 int main()//write 3 { 4 int fd = 0; 5 char buff[1024] = {0}; 6 //建立管道文件 7 if((-1 == mkfifo("myfifo",0644)) && errno != EEXIST) 8 error_exit("fail to mkfifo!"); 9 //只读打开 10 if(-1 == (fd = open("myfifo",O_WRONLY))) 11 error_exit("fail to open!"); 12 13 while(1) 14 { 15 //从终端输入数据 写到管道文件中 供读端去读 16 fgets(buff,sizeof(buff),stdin); 17 write(fd,buff,strlen(buff)+1); 18 } 19 return 0; 20 }
read.c
1 //多路复用IO 2 #include"head.h" 3 int main()//read 4 { 5 int fd=0; 6 fd_set rdfds,tmpfds;//定义读文件描述符 7 char buff[1024]={0}; 8 int maxfd=0;//定义最大文件描述符 9 10 if((-1==mkfifo("myfifo",0644))&&errno!=EEXIST) 11 error_exit("fail to mkfifo!"); 12 // 13 if(-1==(fd=open("myfifo",O_RDONLY))) 14 error_exit("fail to open!"); 15 FD_ZERO(&rdfds);// 将文件描述符集合清空 16 FD_SET(0,&rdfds);//将0文件描述符加到文件描述符当中 17 FD_SET(fd,&rdfds);//将fd文件描述符加到文件描述符当中 18 19 maxfd=fd+1; 20 tmpfds=rdfds;//复制 21 while(1) 22 { 23 rdfds=tmpfds;//重新加载所有描述符到文件描述符集合中 24 //监听多个文件描述符集合,一旦有一个来数据后对应描述符阻塞,其他描述符被剔除。 25 select(maxfd,&rdfds,NULL,NULL,NULL); 26 if(FD_ISSET(0,&rdfds))//文件描述符0是否产生事件 27 { 28 //自己在终端输入和打印 29 fgets(buff,sizeof(buff),stdin); 30 printf("stdin:%s",buff); 31 } 32 if(FD_ISSET(fd,&rdfds))//文件描述符fd是否产生事件 33 { 34 //从管道中读数据并打印 35 read(fd,buff,sizeof(buff)); 36 printf("fifo:%s",buff); 37 } 38 } 39 return 0; 40 } 41 42 /* 43 #include <sys/time.h> 44 #include <sys/types.h> 45 #include <unistd.h> 46 47 int select(int nfds, fd_set *readfds, fd_set *writefds, 48 fd_set *exceptfds, struct timeval *timeout); 49 //监听多个文件描述符集合,一旦有一个来数据后对应描述符阻塞,其他描述符被剔除。 50 //最大fd数值+1/读fd集合/写fd集合/额外的fd集合/阻塞等待的时间 51 52 void FD_CLR(int fd, fd_set *set); //将fd从fd集合中清除 53 int FD_ISSET(int fd, fd_set *set);//判断fd是否产生事件 54 void FD_SET(int fd, fd_set *set); //添加fd到fd集合中去 55 void FD_ZERO(fd_set *set); //清空fd集合 56 */

浙公网安备 33010602011771号