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

linux C 语言开发 (九) 进程间通讯--管道

    文章的目的为了记录使用C语言进行linux 开发学习的经历。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。

相关链接:

linux C 语言开发 (一) Window下用gcc编译和gdb调试

linux C 语言开发 (二) VsCode远程开发 linux

linux C 语言开发 (三) 建立云服务器

linux C 语言开发 (四) linux系统常用命令

linux C 语言开发 (五) linux系统目录结构

linux C 语言开发 (六) 程序的编辑和编译(vim、gcc)

linux C 语言开发 (七) 文件 IO 和标准 IO

linux C 语言开发 (八) 进程基础

linux C 语言开发 (九) 进程间通讯--管道

linux C 语言开发 (十) 进程间通讯--信号

Linux C到Android App开发推荐链接(入门十二章):

开源 java android app 开发(一)开发环境的搭建_csdn 开源 java android app-CSDN博客

开源 java android app 开发(一)开发环境的搭建-CSDN博客

开源 java android app 开发(二)工程文件结构-CSDN博客

开源 java android app 开发(三)GUI界面布局和常用组件-CSDN博客

开源 java android app 开发(四)GUI界面重要组件-CSDN博客

开源 java android app 开发(五)文件和数据库存储-CSDN博客

开源 java android app 开发(六)多媒体使用-CSDN博客

开源 java android app 开发(七)通讯之Tcp和Http-CSDN博客

开源 java android app 开发(八)通讯之Mqtt和Ble-CSDN博客

开源 java android app 开发(九)后台之线程和服务-CSDN博客

开源 java android app 开发(十)广播机制-CSDN博客

开源 java android app 开发(十一)调试、发布-CSDN博客

开源 java android app 开发(十二)封库.aar-CSDN博客

linux C到.net mvc开发推荐链接:

开源C# .net mvc 开发(一)WEB搭建_c#部署web程序-CSDN博客

开源 C# .net mvc 开发(二)网站快速搭建_c#网站开发-CSDN博客

开源 C# .net mvc 开发(三)WEB内外网访问(VS发布、IIS配置网站、花生壳外网穿刺访问)_c# mvc 域名下不可訪問內網,內網下可以訪問域名-CSDN博客

开源 C# .net mvc 开发(四)工程结构、页面提交以及显示_c#工程结构-CSDN博客

开源 C# .net mvc 开发(五)常用代码快速开发_c# mvc开发-CSDN博客、

内容:讲述进程间的IPC通讯,匿名管道和有名管道。IPC通讯对比文件读写,最简单的理解就是


 

目录:

1.IPC通讯        

2.匿名管道

3.有名管道

一、IPC通讯--管道

       Linux 提供了多种专门为 IPC 设计的机制,它们主要在内存中进行操作,速度极快,并提供了良好的同步和互斥机制。主要可以分为以下几类:

1. 基于通信的 IPC (用于交换数据)
这类机制关注于进程间的数据流动。

管道 (Pipe): 最基本的 IPC。分为匿名管道(用于有亲缘关系的进程,如父子进程)和命名管道 (FIFO)(用于无亲缘关系的进程)。数据是单向流动的字节流。

消息队列 (Message Queue): 消息的链表,存放在内核中。进程可以向队列中添加消息或读取消息。每个消息是一个数据块,有特定的类型,比管道更有结构。

信号 (Signal): 一种异步通知机制,用于通知进程某个事件已经发生(如 Ctrl+C 发送 SIGINT)。它携带的信息量很小(只有一个信号编号),主要用于控制,而非数据传输。

套接字 (Socket): 功能最强大、最通用的 IPC 机制,不仅可以用于同一台主机的进程间通信(Unix Domain Socket),还可以用于网络上的不同主机间的通信。TCP/IP socket 就是最著名的例子。

二、匿名管道

无名管道是最古老的进程通信方式, 有如下两个特点:

1. 只能用于有关联的进程间数据交互, 如父子进程, 兄弟进程, 子孙进程, 在目录中看不到文件节点, 读写文件描述符存在一个 int 型数组中。

2. 只能单向传输数据, 即管道创建好后, 一个进程只能进行读操作, 另一个进程只能进行写操作,读出来字节顺序和写入的顺序一样。

函数int pipe(int pipefd[2])
头文件#include <unistd.h>
参数 pipefd[2]一个 int 型数组, 表示管道的文件描述符, pipefd[0]为读, pipefd[1]为写, 如下图所示:
返回值成功返回 0, 失败返回-1
功能创建无名管道

无名管道使用步骤:
1. 调用 pipe()创建无名管道;
2. fork()创建子进程, 一个进程读, 使用 read(), 一个进程写, 使用 write()。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(void)
{
char buf[32] = {0};
pid_t pid;
// 定义一个变量来保存文件描述符
// 因为一个读端, 一个写端, 所以数量为 2 个
int fd[2];
// 创建无名管道
pipe(fd);
printf("fd[0] is %d\n", fd[0]);
printf("fd[2] is %d\n", fd[1]);
// 创建进程
pid = fork();
if (pid < 0)
{
printf("error\n");
} i
f (pid > 0)
{
int status;
close(fd[0]);
write(fd[1], "hello", 5);
close(fd[1]);
wait(&status);
exit(0);
} i
f (pid == 0)
{
close(fd[1]);
read(fd[0], buf, 32);
printf("buf is %s\n", buf);
close(fd[0]);
exit(0);
}
return 0;
}

演示效果

三、有名管道

有名管道中可以很好地解决在无关进程间数据交换的要求, 并且由于它们是存在于文件系统中的, 这也提供了一种比匿名管道更持久稳定的通信办法。 有名管道在一些专业书籍中叫做命名管道, 它的特点是1.可以使无关联的进程通过 fifo 文件描述符进行数据传递; 2.单向传输有一个写入端和一个读出端, 操作方式和无名管道相同。

 函数详解如下所示:

函数int mkfifo(const char *pathname, mode_t mode)
头文件#include <sys/types.h> #include <sys/stat.h>
参数 pathname有名管道的路径和名称
参数 mode权限
返回值成功返回 0, 失败返回-1

有名管道使用步骤:

1. 使用 mkfifo()创建 fifo 文件描述符。

2. 打开管道文件描述符。

3. 通过读写文件描述符进行单向数据传输。

具体代码:

创建两个无关联的进程, 一个进程创建有名管道并写数据, 另一个进程通过管道读数据。输入以下命令创建管道文件, 并查看, 如下图所示:

mkfifo fifo
ls ls -al

fifo_write.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{int ret;char buf[32] = {0};int fd;if (argc < 2){printf("Usage:%s <fifo name> \n", argv[0]);return -1;} if (access(argv[1], F_OK) == 1){ret = mkfifo(argv[1], 0666);if (ret == -1){printf("mkfifo is error \n");return -2;} printf("mkfifo is ok \n");}fd = open(argv[1], O_WRONLY);while (1){sleep(1);write(fd, "hello", 5);} close(fd);return 0;
}

fi fo_read.c:
 

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main(int argc, char *argv[])
{char buf[32] = {0};int fd;if (argc < 2){printf("Usage:%s <fifo name> \n", argv[0]);return -1;} fd = open(argv[1], O_RDONLY);while (1){sleep(1);read(fd, buf, 32);printf("buf is %s\n", buf);memset(buf, 0, sizeof(buf));} close(fd);return 0;
}

编译和演示效果

注意需要先mkfifo fifo,再便宜 fifo_read.c,fifo_write.c


文章转载自:

http://zYtTDis1.tpyjr.cn
http://K8uajruz.tpyjr.cn
http://hgQV8dZa.tpyjr.cn
http://7z3OXqVI.tpyjr.cn
http://1YTyfk9r.tpyjr.cn
http://hYIghtj1.tpyjr.cn
http://F5PQWXaW.tpyjr.cn
http://shxzd9vH.tpyjr.cn
http://HZ1gX4qJ.tpyjr.cn
http://brWVSWsG.tpyjr.cn
http://XM6phJmx.tpyjr.cn
http://p05LidLu.tpyjr.cn
http://Sv82jHPS.tpyjr.cn
http://EIP4GSW3.tpyjr.cn
http://O4YibLti.tpyjr.cn
http://8oLUgfyA.tpyjr.cn
http://NZaklOR3.tpyjr.cn
http://6QwHLAit.tpyjr.cn
http://GYwjGoFu.tpyjr.cn
http://JYa2qYgN.tpyjr.cn
http://SMXyjUXS.tpyjr.cn
http://kFN45fas.tpyjr.cn
http://r3g97Aey.tpyjr.cn
http://Jtm9qpHw.tpyjr.cn
http://WTLLMhxk.tpyjr.cn
http://akQZPpvC.tpyjr.cn
http://8YSUb75l.tpyjr.cn
http://ksjBquDq.tpyjr.cn
http://Mzyaduxc.tpyjr.cn
http://vNsV4LWO.tpyjr.cn
http://www.dtcms.com/a/382609.html

相关文章:

  • LinuxC++项目开发日志——高并发内存池(5-page cache框架开发)
  • MATLAB基于组合近似模型和IPSO-GA的全焊接球阀焊接工艺参数优化研究
  • SpringSecurity的应用
  • 算法题(206):方格取数(动态规划)
  • 第十六周周报
  • [硬件电路-193]:双极型晶体管BJT与场效应晶体管FET异同
  • ID3v2的header中的扩展标头(Extended Header),其Size字段如何计算整个ID3的长度?
  • 【51单片机】【protues仿真】基于51单片机的篮球计时计分器系统
  • Linux -- 权限的理解
  • Java零基础学习Day10——面向对象高级1
  • 解析通过base64 传过来的图片
  • Redis 持久化策略
  • STM32---PWR
  • 0913刷题日记
  • Java基础面试篇(7)
  • 4-机器学习与大模型开发数学教程-第0章 预备知识-0-4 复数与指数形式(欧拉公式)
  • TA-VLA——将关节力矩反馈融入VLA中:无需外部力传感器,即可完成汽车充电器插入(且可多次自主尝试)
  • 从0到1开发一个商用 Agent(智能体),Agent零基础入门到精通!_零基础开发aiagent 用dify从0到1做智能体
  • android 消息队列MessageQueue源码阅读
  • Gtest2025大会学习记录(全球软件测试技术峰会)
  • oneshape acad数据集 sam-dataset
  • 堆(优先队列)
  • 【卷积神经网络详解与实例】7——经典CNN之AlexNet
  • Digital Clock 4,一款免费的个性化桌面数字时钟
  • mysql 必须在逗号分隔字符串和JSON字段之间二选一,怎么选
  • 分布式锁介绍与实现
  • 海盗王客户端dx9的64位release版测试
  • MX模拟赛总结
  • FLEXSPI_Init 硬件故障问题
  • Linux进程概念(下):进程地址空间