当前位置: 首页 > news >正文

Linux进程通信之管道

进程通信之管道

管道其实就是一个特殊的文件。管道通信是半双工通信,即数据的流动是单向流动的,大致分为匿名管道和命名管道。

匿名管道,是一个只存在于内存中,不存在于文件系统中,并且只能在具有亲缘关系的进程之间使用,即父子进程和兄弟进程。一个进程在管道的一段写数据,一个进程在管道的另一边读数据,这就是匿名管道。

命名管道,是一个不止存在于内存中,在文件系统上有自己名字的一个文件,任何进程任何时间都能通过文件名和路径去使用这个管道,但是数据还是存储在内存中。

匿名管道的实现

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<string.h>
#include<stdlib.h>int main(int argc, char const *argv[])
{int fd[2];pid_t pid;char buffer[128];if(pipe(fd) < 0)printf("creat pipe faild\n");pid = fork();if(pid < 0){printf("create fork fail\n");}else if (pid > 0){//父进程sleep(3);printf("this is father,pid = %d\n", getpid());close(fd[0]);write(fd[1], "hello highgo", strlen("hello highgo"));wait(NULL);}else {//子进程printf("this is child,pid = %d, ppid = %d\n",getpid(),getppid());close(fd[1]);read(fd[0],buffer,sizeof(buffer));printf("%s\n",buffer);}return 0;
}pipe_test.c

在上述代码中,fd[2]就是匿名管道,fd[0]是读的区域,fd[1]是写的区域。

如果内容在写之前读取,则该进程将会被挂起。

文件缓冲区是有限的,可以通过命令查看

cat /proc/sys/fs/file-max

在这里插入图片描述
可以通过ulimit进行修改

深入了解Linux管道缓冲大小设置 (linux pipe 缓冲大小) – 后浪云 (idc.net)

命名管道

命名管道的实现分为两个文件,这两个文件分别为两个进程。

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <limits.h>#ifndef PIPE_BUF
#define PIPE_BUF 4192
#endifint main(int argc, char const *argv[])
{const char* fifoname = "my_fifo";int pipe_fd = -1;int data_fd = -1;int res = 0;char pipe_buffer[PIPE_BUF + 1] = {0};int bytes_read = 0;int bytes_sent = 0;//检查文件是否已经存在if(access(fifoname,F_OK) == -1){res = mkfifo(fifoname, 0600);if(res != 0){printf("create fifo faild");exit(EXIT_FAILURE);}}    //需要往管道里面写东西,所以以读写的方式打开pipe_fd = open(fifoname, O_WRONLY);//只需要读取data.txt文件里面的东西,不需要写入,所以只读的方式打开data_fd = open("data.txt", O_RDONLY);if (pipe_fd != -1){//获取写入管道的字节大小bytes_read = read(data_fd, pipe_buffer, PIPE_BUF);//将读取的数据的最后一位设置为字符串的结束符号pipe_buffer[bytes_read] = '\0';while (bytes_read > 0){/* 将读取到缓冲区的数据写入到管道中去 */res = write(pipe_fd, pipe_buffer, bytes_read);if(res == -1){printf("write error on pipe\n");exit(EXIT_FAILURE);}//记录读取的到的所有字节数大小bytes_sent += res;bytes_read = read(data_fd, pipe_buffer, PIPE_BUF);pipe_buffer[bytes_read] = '\0';}//关闭释放资源close(data_fd);close(pipe_fd);}else{close(data_fd);perror("fifofile open error:");exit(EXIT_FAILURE);}printf("read finished,have sent %d bytes,pid = %d", bytes_sent, getpid());return 0;
}mkfifo_w.c

这个进程会将当前已经存在的一个data.txt文件打开,读取其中的数据,然后将其写入管道my_fifo中,供其他进程进行读取,并且循环读取该文件并写入管道。

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <limits.h>#ifndef PIPE_BUF
#define PIPE_BUF 4192
#endifint main(int argc, char const *argv[])
{const char  *fifoname = "my_fifo";int         pipe_fd = -1;int         data_fd = -1;int         res = 0;char        pipe_buffer[PIPE_BUF + 1] =  {0};int         bytes_read = 0;int         bytes_write = 0;//打开管道文件,以读写的权限,这里其实以读的权限即可pipe_fd = open(fifoname, 0600);//需要将读取的信息写入该文件,故赋予读写的权限还有创建的权限data_fd = open("data_fuben.txt", O_WRONLY|O_CREAT, 0644);if(pipe_fd != -1){do{res = read(pipe_fd, pipe_buffer, PIPE_BUF);bytes_write = write(data_fd, pipe_buffer, res);bytes_read += res;}while(res > 0);close(data_fd);close(pipe_fd);}else{close(data_fd);perror("fifofile open error:");exit(EXIT_FAILURE);}printf("Process %d finished, %d bytes read\n", getpid(), bytes_read);return 0;
}mkfifo_w.c

匿名管道和命名管道差异

在这里插入图片描述
不同之处:

  1. 可见性与持久性:命名管道(FIFO)在文件系统中可见,并作为特殊文件存在,即使创建进程退出后仍然保留,以便后续使用。而管道(pipe)则不可见,且在使用它的进程退出后自动消失。
  2. 通信范围:命名管道(FIFO)允许不相关的进程通过打开管道文件进行通信,而管道(pipe)通常用于具有亲缘关系的进程之间的通信,如父子进程。
  3. 缓冲区大小:管道(pipe)的缓冲区大小在不同系统中可能有所不同,而命名管道(FIFO)作为文件系统中的特殊文件,其缓冲区大小可能受到文件系统的限制。
  4. 有名与无名:命名管道(FIFO)有具体的名称,可以通过名称来引用和访问;而管道(pipe)通常是匿名的,没有具体的名称标识。

http://www.mrgr.cn/news/68556.html

相关文章:

  • 十款外贸软件盘点,专注企业订单业务管理
  • YOLO可视化界面,目标检测前端页面。
  • 设计模式之——观察者模式
  • MySQL OnlineDDL添加字段
  • Audio-Language Models
  • Ubuntu22.04之解决:断开有线网后,需要重启才能联网问题(二百七十五)
  • oracle数据坏块处理(三)-数据抽取插入到新表中
  • RHCE—web服务器
  • VR的左右眼渲染方法
  • 08 反射与注解
  • 【Linux】解锁操作系统潜能,高效线程管理的实战技巧
  • vue3使用easy-player播放hls监控流
  • AIGC--如何在内容创作中合理使用AI生成工具?
  • 1 天通关 AWS AI 认证,AWS AI 从业者证书最强考试指南
  • LangChain 快速入门
  • 信息安全工程师(83)Windows操作系统安全分析与防护
  • 淘宝商品详情API大揭秘:用Python开启探险之旅
  • 自动驾驶中,2d图像目标检测(分割),融合激光雷达点云信息
  • ChatGLM2-6B微调记录【1】
  • 【计网不挂科】计算机网络期末考试——【选择题&填空题&判断题&简述题】题库(2)
  • ​解决‌win11无法打开msi安装程序包的方法‌
  • AI预测体彩排3采取888=3策略+和值012路+胆码+通杀1码测试11月8日升级新模型预测第128弹
  • 虚假新闻检测:CSV格式数据集的预处理与模型选择
  • 改变财务规划思维方式,迎接创新技术新时代
  • 数据分析的力量如何驱动商业决策和创新发展
  • 文件系统和日志管理 附实验:远程访问第一台虚拟机日志