linux进程间通信编程-管道通信
linux 进程间通信编程,管道通信的实验
代码分析
程序分析
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
#include <string.h>
#include <sys/types.h> //mkfifo
#include <sys/stat.h> //mkfifo
// 定义FIFO有名管道名
#define FIFO1 "in1"
#define FIFO2 "in2"
//设定缓冲区大小
#define BUF_SIZE 512
//超时时间
#define DELAY_TIME 60
//多路复用文件数目
#define IN_FILES 3
#define MAX(a,b) ((a) > (b)? (a) : (b))
int main()
{
int fds[IN_FILES];
char buf[BUF_SIZE];
int i, res, real_read, maxfd;
fd_set inset, tmpset;
struct timeval tv; //超时时间设置
fds[0] = 0; //标准输入设备
//创建两个有名管道
//access - check real user's permissions for a file
//#include <unistd.h>
//int access(const char *pathname, int mode);
//mode: F_OK, R_OK, W_OK, and X_OK.
//mkfifo - make a FIFO special file (a named pipe)
//#include <sys/types.h>
//#include <sys/stat.h>
//int mkfifo(const char *pathname, mode_t mode);
if((access(FIFO1, F_OK)) == -1) //如果 FIFO1 有名管道不存在
{
if((mkfifo(FIFO1, 0666)) == -1)
{
perror("Error FIFO1 create!");
exit(-1);
}
}
if((access(FIFO2, F_OK)) == -1) //如果 FIFO2 有名管道不存在
{
if((mkfifo(FIFO2, 0666)) == -1)//指明创建一个有名管道且存取权限为0666,即创建者、与创建者同组的用户、其他用户对该有名管道的 访问权限 都是 可读可写。
{
perror("Error FIFO2 create!");
exit(-1);
}
}
//以只读非阻塞的方式打开两个文件
if((fds[1] = open(FIFO1, O_RDONLY|O_NONBLOCK)) == -1)
{
perror("Error FIFO1 open");
exit(-1);
}
if((fds[2] = open(FIFO2, O_RDONLY|O_NONBLOCK)) == -1)
{
perror("Error FIFO2 open");
exit(-1);
}
//以下为select函数作准备
//取出两个文件描述符中的较大者
maxfd = MAX(fds[1], fds[2]);
//初始化读集合inset
FD_ZERO(&inset);
//在读文件描述符中加入相应的描述符
for(i = 0; i < IN_FILES; i++)
{
FD_SET(fds[i], &inset);
}
tv.tv_sec = DELAY_TIME;
tv.tv_usec = 0;
//使用select函数循环测试监测的读文件描述符集中是否有准备就绪的
while(FD_ISSET(fds[0], &inset) || FD_ISSET(fds[1], &inset) || FD_ISSET(fds[2], &inset))
{
tv.tv_sec = DELAY_TIME;
tv.tv_usec = 0;
tmpset = inset; //使用临时文件描述符集,避免每次初始化
//int select(int nfds, fd_set *readfds, fd_set *writefds,
// fd_set *exceptfds, struct timeval *timeout);
res = select(maxfd + 1, &tmpset, NULL, NULL, &tv);
//根据函数返回值进行处理
switch (res)
{
case -1:
{
perror("Error Select");
exit(-1);
}
break;
case 0:
{
printf("超时\n");
return 1;
}
break;
default:
{
for (i = 0; i < IN_FILES; i++)
{
if (FD_ISSET(fds[i], &tmpset))
{
memset(buf, 0, BUF_SIZE);
real_read = read(fds[i], buf, BUF_SIZE);
if (real_read == -1 )
{
if (errno != EAGAIN)
{
return 1;
}
} // 文件读出错处理
else if(!real_read)
{
FD_CLR(fds[i], &inset);
close(fds[i]);
}
else // 文件读正常处理
{
if (i == 0)
{ // 标准终端输入处理(文件描述符是0)
if ((buf[0] == 'q') || (buf[0] == 'Q'))
{
return 0;
}
}
else // FIFO输入处理
{
buf[real_read] = '\0';
printf("FIFO%d: %s", i, buf);
} //end if 输入处理
} //end if 文件处理
} //end if 文件就绪处理
} //end for 文件轮询
}
break;
} //end switch
} //end while
return 0;
}
执行结果
同样没什么解释的,检测到in1,in2可读,就返回,在输入处理中打印到终端,检测到标准输入时,判断是否是“q/Q”,是则退出检测,超时后自动退出
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 不听话的兔子君!