一 、管道(Pipe、Fifo)
1. 无名管道 pipe:适用于亲缘关系进程间的、一对一的通信。
2. 有名管道 fife : 适用于任何进程间的一对一,多对一的通信。
二、 无名管道(pipe)
1. 管道是一种文件,无名管道没有文件的名字。
2. 无名管道的特点:
1) 因为没有具体的文件名字,所以没有在磁盘里形成具体的文件。
2) 虽然是文件类型,但是不能用 lseek 定位。
3) 退出程序后,程序内的管道资源会被释放,下次运行需要再创建。
4) 只能用于亲缘进程(父子,兄弟,爷孙)
5) pipe 是在fork之前创建的,(当有四个端口时,两个读,两个写,才能实现双向通信)。
6)无名管道是在内核创建出来的
7) 属于半双工通信
8) 不能用open打开
9)写操作没有原子性。
3. 函数使用
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#define MSG_LENGTH 20 // 宏定义
int main()
{
// 创建管道
int pipefd[2] = {0};
int pipe_ret = pipe(pipefd);
if(pipe_ret == -1)
{
perror("pipe");
exit(-1);
}
// 创建父子进程
int pid = fork();
if(pid == -1)
{
perror("fork");
exit(-1);
}
else if(pid == 0) //子进程
{
char msg_data[MSG_LENGTH];
memset(msg_data,0,MSG_LENGTH);
printf("请输入发给父亲的信息:");
scanf("%s",msg_data);
/*发送*/
write(pipefd[1],msg_data,strlen(msg_data));
}
else // 父进程
{
char msg_data[MSG_LENGTH];
memset(msg_data,0,MSG_LENGTH);
/*接收*/
read(pipefd[0],msg_data,MSG_LENGTH);
printf("儿子说:%s\n",msg_data);
}
/*共享区域*/
close(pipefd[0]);
close(pipefd[1]);
if(pid > 0)
wait(NULL);
exit(0);
}
三 、 有名管道(fife)
1. 基本概念:
有名管道:有名字的管道,所有的具体文件,都是在闪存里面存放的
2. 特点:
1) 血缘 和 非血缘都可以用
2) 可用 open 打开,
3) 不能用 lseek 定位
4) 写操作有原子性
5) 全双工
6) 退出程序后,有名管道可一直使用,直到把文件删除
2. 实现代码
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#define FIFO_PATH "/tmp/dante_fifo"
int main()
{
//先判断管道存不存在
if(access(FIFO_PATH,F_OK))
{
umask(0000);
mkfifo(FIFO_PATH,0777);
}
int fifo_fd = open(FIFO_PATH,O_RDWR);
if(fifo_fd == -1)
{
perror("open");
return -1;
}
char msg_data[10];
while(1)
{
memset(msg_data,0,10);
printf("请输入要发给小红的信息");
scanf("%s",msg_data);
write(fifo_fd,msg_data,strlen(msg_data));
}
close(fifo_fd);
return 0;
}