管道
前言
通信要解决的实际问题,就是多个进程之间如何实现数据的收发提示:以下是本篇文章正文内容,下面案例可供参考
一、原理
分为两种:有名管道,无名管道(属于半双工)
全双工:通信双方在任何时刻都能互相收发信息,收发信息可以同时进行不受任何影响
半双工:通信双方在任意时刻都只能是一方发生,一方接收,不能同时两边都收发
二、无名管道相关操作
1.无名管道具体实例
父子进程采用无名管道通信–>双向 通信 思路:采用两个无名管道实现
fd[2] --> 存放的是无名管道读写端的文件描述符
fd[0] --> 读端的文件描述符
fd[1] --> 写端的文件描述符
代码如下(示例):
int state;
int fd[2];
int otherfd[2];
char buf[100];
char otherbuf[100];
int ret;
//创建一个无名管道
ret = pipe(fd);
if(ret == -1){
perror("pipe");
return -1;
}
//再创建一个无名管道
ret = pipe(otherfd);
if(ret == -1){
perror("pipe");
return -1;
}
//创建一个子进程
pid_t id = fork();
if(id>0){ //父亲
while(1){
//读取第一个无名管道中的内容
bzero(buf,100);
bzero(otherbuf,100);
read(fd[0],buf,100);
if(strcmp(buf,"quit")==0){
break;
}
printf("my son say : %s\n",buf);
printf("please input information to son : \n");
scanf("%s",otherbuf);
//把信息写入到第二个无名管道中
write(otherfd[1],otherbuf,strlen(otherbuf));
}
}
//儿子
else {
while(1){
bzero(buf,100);
bzero(otherbuf,100);
printf("please input information to father : \n");
scanf("%s",buf);
//把键盘输入的内容写入到第一个无名管道的写端
write(fd[1],buf,strlen(buf));
if(strcmp(buf,"quit")==0){
break;
}
//从第二个无名管道中读取内容
read(otherfd[0],otherbuf,100);
printf("my father say : %s\n",otherbuf);
}
//结束子进程
exit(0);
}
close(fd[0]);
close(fd[1]);
close(otherfd[0]);
close(otherfd[1]);
//回收子进程
wait(&state);
printf("recovery son :%d\n",WEXITSTATUS(state));
2.无名管道的特点
1)如果管道中没有数据可读,read会阻塞当前进程
2)无名管道不会生成管道文件
3)无名管道有固定的读写端
4)无名管道只能用于具有血缘关系多个进程之间(父子进程、兄弟进程)
三、有名管道相关操作
1.有名管道具体实例
mkfifo函数
第一个参数:生成的有名管道的路径
第二个参数:权限 0777
有名管道用于两个没有任何关系的进程间通信
有名管道在创建之前必须判断一下管道文件是否存在
方法一:使用errno去判断
方法二:使用access函数判断
扩充: int access(const char *path,int amode);
path–>你要判断的文件的路径
amode–> R_OK 判断文件是否可读
W_OK 判断文件是否可写
X_OK 判断文件是否可执行
F_OK 判断文件是否存在
代码如下(示例):
int ret;
int fd;
char buf[100];
//创建有名管道
ret = mkfifo("/home/gec/myfirst",0777);
if(ret==-1){
printf("error number is : %d\n",errno);
//判断错误的原因,只关心是否是因为管道存在导致这个错误
if(errno == EEXIST){
printf("had exist!\n");
}
//错误的原因不是文件存在
else{
perror("mkfifo");
return -1;
}
}
//打开你刚才新建的那个管道文件
fd = open("/home/gec/myfirst",O_RDWR);
if(fd == -1){
perror("open");
return -1;
}
//给p2发送信息
while(1){
bzero(buf,100);
printf("input information to p2:\n");
scanf("%s",buf);
write(fd,buf,strlen(buf));
}
2.有名管道的特点
1)有名管道会生成对应的管道文件(用于等一会进程间通信)
2)有名管道不能再同一个路径下重复创建,并且只能在纯粹的linux环境中创建,不能在共享文件夹中新建
3)有名管道可以用于任意两个进程间通信(可以是父子进程,也可以是没有任何关系的两个进程)
4)有名管道没有固定的读写端,只要打开成功,直接读写操作
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了进程间通信的一种办法----管道,此外还有信号等,将在后序讲解,希望对大家有所帮助。