当前位置: 代码迷 >> 综合 >> 进程间通信(二)——pipe
  详细解决方案

进程间通信(二)——pipe

热度:10   发布时间:2024-01-11 04:01:47.0

无名管道:PIPE

Linux内核中的管道

PIPE的内核层实现

我们可以使用locate命令来查看文件在那个位置,比find好用!!!!

sudo apt install mlocate

locate 文件名

struct pipe_inode_info {
struct mutex mutex;
wait_queue_head_t rd_wait, wr_wait;
unsigned int head;
unsigned int tail;
unsigned int max_usage;
unsigned int ring_size;
#ifdef CONFIG_WATCH_QUEUE
bool note_loss;
#endif
unsigned int nr_accounted;
......
#endif
};

通信原理

  • 管道是一个文件(pipefs):
    • 内核将一个缓冲区与管道文件进行关联、封装
    • 用户可通过open/read/write/close等I/O接口进行读写

Pipe管道编程

创建一个管道

  • 函数原型:
    • int pipe(int pipefd[2]);
    • int pipe2(pipefd[2], iny flags);
  • 函数参数:管道的两个文件描述符:一个用来读(fd[0])、一个用来写(fd[1] )

编程实例

  • 单向通道
  • 双向通道

fd[1]是写端

fd[0]是读端

  1. 定义int fd[2]; //fd[1]是写端, fd[0]是读端
  2. fork创建一个子进程
  3. 子进程写
  4. 父进程读

单向通道

/**********************************
*@file pipe1.c
*@brief  
*@author lizhuofan
*@date 2022-03-09
*************************************/#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>#define handle_error(s) \{perror(s);exit(-1);}int main(int argc, char *argv[])
{int pipe_fd[2];int ret_from_fork;if (pipe(pipe_fd) == -1)handle_error("pipe");ret_from_fork = fork();if (ret_from_fork < 0)handle_error("fork");if (ret_from_fork == 0){char str[100] = {0};printf("This is son process\n input");scanf("%s", str);write(pipe_fd[1], str, strlen(str));close(pipe_fd[1]);_exit(EXIT_SUCCESS);}if (ret_from_fork > 0){char buf[100];read(pipe_fd[0], buf, 100);printf("%s\n", buf);close(pipe_fd[0]);exit(EXIT_SUCCESS);}return 0;
}
  • 双向通道
  1. 定义2个管道,pipe_fd1[2], pipe_fd2[2]
  2. fork,创建一个父子进程,用来读写
  3. 在子进程定义两个缓冲区,用来收发数据,读完写完记得关闭管道
  4. 在父进程定义两个缓冲区,用来收发数据,读完写完记得关闭管道
/**********************************
*@file pipe1.c
*@brief  
*@author lizhuofan
*@date 2022-03-09
*************************************/#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>#define handle_error(s) \{perror(s);exit(-1);}int main(int argc, char *argv[])
{int pipe_fd1[2];int pipe_fd2[2];int ret_from_fork;if (pipe(pipe_fd1) == -1 || pipe(pipe_fd2) == -1)handle_error("pipe");ret_from_fork = fork();if (ret_from_fork < 0)handle_error("fork");if (ret_from_fork == 0){char read_buf1[100]  = {0};char write_buf1[100] = {0};printf("This is son process\n input");gets(write_buf1);write(pipe_fd1[1], write_buf1, strlen(write_buf1));close(pipe_fd1[1]);read (pipe_fd2[0], read_buf1, 100);printf("%s\n", read_buf1);close(pipe_fd2[0]);_exit(EXIT_SUCCESS);}if (ret_from_fork > 0){char read_buf2[100] = {0};char write_buf2[100]= {0};read(pipe_fd1[0], read_buf2, 100);printf("%s\n", read_buf2);close(pipe_fd1[0]);printf("father process:");gets(write_buf2);write(pipe_fd2[1], write_buf2, strlen(write_buf2));close(pipe_fd2[1]);exit(EXIT_SUCCESS);}return 0;
}