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 */

posted @ 2017-03-13 21:46  bkycrmn  阅读(163)  评论(0)    收藏  举报