【Linux学习】进程间通信 (1) —— 管道

下面是有关进程通信中管道的相关介绍,希望对你有所帮助!

小海编程心语录-CSDN博客

1. 进程通信的基本概念

1.1 概念

进程间通信简称 IPC ,指两个进程之间的通信。 IPC的方式通常有管道(包括无名管道和命名管道)、消息队列、信号量、共享存储、Socket、Streams等。其中 Socket和Streams支持不同主机上的两个进程IPC。

1.2 目的

  1. 数据传输:一个进程需要将它的数据发送给另一个进程。
  2. 资源共享:多个进程之间共享同样的资源。
  3. 通知事件:一个进程需要向另一个或一组进程发送消息,通知它们发生了某种事件。
  4. 进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),该控制进程希望能够拦截另一个进程的所有操作,并能够及时知道它的状态改变。

1.3 通信方式 

  1. UNIX IPC: 管道、FIFO、信号
  2. System V IPC: 信号量、消息队列、共享内存
  3. Socket IPC: 基于Socket进程间通信

2. 管道 

把一个进程连接到另一个进程的数据流称为管道,是一个半双工的通信方式。

管道分为有名管道无名管道两种,它们的区别是:

无名管道只能在有亲缘关系的进程之间进行通信。

有名管道又称为命名管道,可以在任意两个进程之间进行通信。

2.1 无名管道 

//函数原型
#include <unistd.h>int pipe( int fd[2] );

匿名管道适用于一对一的、具有亲缘关系的进程间的通信

是一个半双工的通信方式,具有固定的读端和写端。

管道可以看做是一种特殊的文件,对管道的读写可以使用普通的read() ,write()函数,但管道不属于任何文件系统的,只存在于内存中。

2.1.1 如何操作无名管道

  1. 创建 :(pipe函数用来创建无名管道)
  2. 操作 :(read读;write写)  写是 fd[1],读是 fd[0]
  3. 关闭操作端口 :(close)

2.1.2 示例代码 

#include <stdio.h> 
#include <unistd.h> 
#include <sys/wait.h> 
#include <string.h> 
#include <sys/types.h> 
#include <stdlib.h> int main()
{//创建无名管道int fd[2];pipe(fd);if(fork() == 0){close(fd[0]);   //读关闭char *buf = "hello world"; write(fd[1], buf, strlen(buf)); //写操作}else{close(fd[1]);  //写关闭char showbuf[100];bzero(showbuf, 100);  //清空缓冲区read(fd[0], showbuf, 100); //读操作printf("txt is :%s\n", showbuf); //打印内容exit(0);}
}

代码运行结果

2.2 有名管道 

//函数原型
#include <sys/types.h>
#include <sys/stat.h>int mkfifo(const char *pathname, mode_t mode);
//  pathname:具名管道的名称 
//  mode:文件权限模式,例如0666

具名管道通常又被称为FIFO,它是对无名管道的一种改进,其更接近普通文件,有文件名、可以open打开、支持read()/write()等读写操作

Linux在共享文件夹下,创建管道文件是创建不了的,运行结果为空,因此要将执行文件移到非共享文件夹下。因为共享文件夹和Windows是共享的,有些文件windows是没有的。

特性

它可以使互不相关的两个进程实现彼此通信

该管道可以通过路径名来指出,并且在文件系统中是可见的。在建立管道之后,两个进程就可以把它当作普通文件进行读写,使用非常方便。

FIFO严格遵循先进先出原则,对管道及FIFO的读总是从开始处返回数据,对它们的写则把数据添加到末尾。有名管道不支持如Iseek()等文件的定位操作

2.2.1 如何操作具名管道

  1. 创建有名管道文件 :(mkfifo即是命令也是函数;mknod也可以创建管道文件)
  2. 打开有名管道 :(open)
  3. 读/写 :(read/write)
  4. 关闭 :(close)

具名管道一旦没有任何读者和写者,系统判定管道处于空闲状态,会释放管道中的所有数据

1.写者

  1. 创建有名管道文件 mkfifo()
  2. 打开有名管道 open()
  3. 创建缓冲区,写内容 buf
  4. 写操作 write()
  5. 关闭有名管道 close()

2.读者

  1. 打开有名管道 open()
  2. 创建缓冲区,清空缓冲区 buf bzero()
  3. 读操作,打印 read()
  4. 关闭有名管道 close()

2.2.2 示例代码 

//读者
#include <stdio.h> 
#include <unistd.h> 
#include <sys/stat.h> 
#include <string.h> 
#include <sys/types.h> 
#include <fcntl.h> 
#include <stdlib.h> int main()
{int fd = open("./fifo", O_RDWR);  //打开有名管道char showbuf[100];   //创建缓冲区bzero(showbuf, 100);  //清空缓冲区read(fd, showbuf, 100);  //读printf("%s\n", showbuf); //打印close(fd);  //关闭return 0;}
//写者
#include <stdio.h> 
#include <unistd.h> 
#include <sys/stat.h> 
#include <string.h> 
#include <sys/types.h> 
#include <fcntl.h> 
#include <stdlib.h> int main()
{mkfifo("./fifo", 0666);    //创建有名管道文件int fd = open("./fifo", O_RDWR);  //打开有名管道char *buf = "hello world";   //写write(fd, buf, strlen(buf));close(fd);   //关闭return 0;}

注意:

在Linux在共享文件夹下,创建管道文件是创建不了的,运行结果为空,因此要将执行文件移到非共享文件夹下,这里我把执行文件放到家目录的test文件夹下了。

打开两个终端执行命令,这里可用Ctrl+shift+n快速打开相同路径下的终端

代码运行结果

3. 相关练习

编写两个程序,一个客户端、一个服务器端,服务器端创建并且监视管道,发现如果有数据就把它保存到指定位置,客户端将当前系统时间和自己的PID写入管道 

3.1 客户端

//cilent 客户端
#include <stdio.h> 
#include <unistd.h> 
#include <sys/stat.h> 
#include <string.h> 
#include <sys/types.h> 
#include <fcntl.h> 
#include <stdlib.h> 
#include <time.h>
int main()
{int fd = open("./fifo", O_RDWR);  //打开有名管道char buf[1000];     //创建缓冲区time_t tim;while(1){bzero(buf,1000);      //清空缓冲区time(&tim);         //时间sprintf(buf,"[%d]:  %s",getpid(),ctime(&tim)); //打印到buf指向的字符串中write(fd,buf,strlen(buf)); //写操作,在日志文件中写入数据sleep(2);}return 0;}

3.2 服务器端 

//server 服务器端
#include <stdio.h> 
#include <unistd.h> 
#include <sys/stat.h> 
#include <string.h> 
#include <sys/types.h> 
#include <fcntl.h> 
#include <stdlib.h> int main()
{mkfifo("./fifo", 0666);    //创建有名管道文件int logfd = open("./log.txt",O_RDWR | O_CREAT,0777); //创建日志文件int fd = open("./fifo", O_RDWR);  //打开有名管道char buf[1000];     //创建缓冲区while(1){bzero(buf,1000);      //清空缓冲区read(fd,buf,1000);     //读取缓冲区数据write(logfd,buf,strlen(buf)); //在日志文件中写入数据}return 0;}

代码运行结果 


如果喜欢请不吝给予三连支持!

小海编程心语录-CSDN博客

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/14783.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python将矩阵转化为灰度图

1.python将矩阵转化为灰度图的方法 要将一个矩阵&#xff08;通常是一个二维数组&#xff0c;其中每个元素代表一个像素的灰度值&#xff09;转换为灰度图&#xff0c;我们可以使用Python的matplotlib库。下面是一个详细的步骤和完整的代码示例&#xff1a; &#xff08;1&am…

【Muduo】缓冲区Buffer类

在 Muduo 网络库中&#xff0c;Buffer类用于处理网络 I/O 中的数据缓冲。防止应用程序读写太快而网络链路收发速度慢导致的速度不匹配问题。这个类封装了一个内部缓冲区&#xff08;使用了vector<char>&#xff09;&#xff0c;并提供了一系列方法来操作这个缓冲区&#…

【Linux网络】端口及UDP

文章目录 1.再看四层2.端口号2.1引入linux端口号和进程pid的区别端口号是如何生成的传输层有了pid还设置端口号端口号划分 2.2问题2.3netstat 3.UDP协议3.0每学一个协议 都要讨论一下问题3.1UDP协议3.2谈udp/tcp实际上是在讨论什么&#xff1f; 1.再看四层 2.端口号 端口号(Po…

//TODO 注释的作用

// TODO 用来标记某处&#xff0c;表示该处含有待办事项&#xff08;尚未解决&#xff09;。其设计本意只是提醒开发者注意&#xff0c;除了代码高亮之外&#xff0c;还可以借助编辑器实现快速定位。 如何使用&#xff1f; 直接在双斜杠后面加 TODO 或者 todo 即可&#xff0c…

CVPR2022医疗图像-GBCNet网络:胆囊癌(GBC)超声(USG)图像检测模型

Surpassing the Human Accuracy:Detecting Gallbladder Cancer from USG Images with Curriculum Learning&#xff1a;超越人类的准确性:基于课程学习的USG图像检测胆囊癌 目录 一、背景与意义 二、介绍 三、网络框架 3.1 区域选择网络 3.2 MS-SoP分类器 3.3 多尺度块 …

抖音运营_抖音电商介绍

截止20年8月&#xff0c;抖音的日活跃数高达6亿。 20年6月&#xff0c;上线抖店 &#xff08;抖音官方电商&#xff09; 一 抖店的定位和特色 1 一站式经营 帮助商家进行 商品交易、店铺管理、客户服务 等全链路的生意经营 2 多渠道拓展 抖音、今日头条、西瓜、抖音火山版…

ASP+ACCESS基于WEB社区论坛设计与实现

摘要&#xff1a;系统主要实现BBS网站全部功能。采用目前应用最为广泛的ASP作为开发工具来开发此系统、以保证系统的稳定性。采用目前最为流行的网页制作工具Dreamweaver和目前最为流行的动画制作工具Flash MX。整个系统从符合操作简便、界面友好、灵活、实用、安全的要求出发&…

首次面试实习岗,有点紧张。。。

首次面试实习岗&#xff0c;有点紧张。。。 文章目录 首次面试实习岗&#xff0c;有点紧张。。。算法1.三角形问题2.一年中第几天问题 提问&#xff1a;一、SpringBoot的配置文件中的数据有哪几种获取方式&#xff0c;分别是怎么获取的&#xff1f;二、Autowire和Resource有什么…

卤菜销售|基于SSM+vue的智能卤菜销售平台的设计与实现(源码+数据库+文档)

智能卤菜销售平台 目录 基于SSM&#xff0b;vue的智能卤菜销售平台的设计与实现 一、前言 二、系统设计 三、系统功能设计 1系统功能模块 2管理员功能模块 3用户功能模块 4商家功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八…

windows查看mysql的版本(三种方法)

方法一&#xff1a;在win r 打开 cmd&#xff0c;在cmd命令状态下&#xff1a;mysql --help 回车即可 方法二&#xff1a;在mysql客户端窗口状态下&#xff1a;输入status并回车即可 在计算机开始菜单搜索以上应用打开即可进入mysql客户端窗口。 方法三&#xff1a;在mys…

【必会面试题】Redis如何实现分布式锁?

目录 一、为什么要使用分布式锁&#xff1f;二、什么是分布式锁&#xff1f;三、什么是Redis分布式锁&#xff1f;四、如何实现Redis分布式锁&#xff1f;1. 基础方法&#xff1a;SETNX EXPIRE2. Lua 脚本3. Redisson 实现4. Redlock 算法 五、JavaRedis分布式锁1. 基于Jedis的…

pikachu-Unsafe Filedownload

任意点击一个图片进行下载&#xff0c;发现下载的url。 http://127.0.0.1/pikachu/vul/unsafedownload/execdownload.php?filenamekb.png 构造payload&#xff1a; 即可下载 当前页面的源码&#xff0c;可以进行路径穿越来下载一些重要的配置文件来获取信息。 http://127.0.…

Android Audio基础——Track构造过程(十)

在 Android 中,Track 通常是指用于播放音频或视频的轨道或通道,用于音频流的控制。在这种语境下,AudioTrack 是用于播放音频的类之一,它提供了直接控制音频数据播放的功能。因此,可以说 AudioTrack 是 Android 中处理音频轨道的一种实现方式之一。 一、Track构造 我们接着…

函数对象引用题目

下列代码的输出是什么&#xff1f; python def func(x): return x1 funcs[func]*5 result[f(0) for f in funcs] print(result) A.[1,1,1,1,1] B.[1,2,3,4,5] C.[0,0,0,0,0] D.[0,1,2,3,4] 3 2 1 答案是A&#xff0c;你答对了吗&#xff1f; 解析&#xff1a; def fu…

前端基础入门三大核心之HTML篇 —— 同源策略的深度解析与安全实践

前端基础入门三大核心之HTML篇 —— 同源策略的深度解析与安全实践 一、同源策略&#xff1a;定义与起源1.1 定义浅析1.2 何为“源”&#xff1f;1.3 起源与意义 二、同源策略的运作机制2.1 限制范围2.2 安全边界 三、跨越同源的挑战与对策3.1 JSONP3.2 CORS3.3 postMessage 四…

VUE 创建组件常见的几种方式

在 Vue.js 中&#xff0c;组件的创建和使用通常遵循以下三种方法&#xff1a; 1. 全局组件 全局组件是通过 Vue.component() 方法创建的&#xff0c;注册后的组件可以在任何新创建的 Vue 实例&#xff08;包括根实例&#xff09;的模板中使用。 Vue.component(my-component,…

【MySQL精通之路】系统变量-持久化系统变量

MySQL服务器维护用于配置其操作的系统变量。 系统变量可以具有影响整个服务器操作的全局值&#xff0c;也可以具有影响当前会话的会话值&#xff0c;或者两者兼而有之。 许多系统变量是动态的&#xff0c;可以在运行时使用SET语句进行更改&#xff0c;以影响当前服务器实例的…

[AI Google] 10个即将到来的Android生态系统更新

新的体验带来了更强的防盗保护、手表电池寿命优化&#xff0c;以及对电视、汽车等的娱乐功能改进。 昨天&#xff0c;我们分享了Android如何以人工智能为核心重新构想智能手机。今天&#xff0c;我们推出了Android 15的第二个测试版&#xff0c;并分享了更多我们改进操作系统的…

java原型模式 (Prototype Pattern) 介绍

原型模式&#xff08;Prototype Pattern&#xff09;是一种创建型设计模式&#xff0c;它通过复制现有的实例来创建新对象&#xff0c;而不是通过实例化类来创建对象。这个模式允许你创建对象时避免复杂的初始化步骤&#xff0c;并且能够动态地创建对象的副本。 原型模式的关键…

Python导入Shapefile到PostGIS的常见问题和解决方案

导入Shapefile到PostGIS的常见问题和解决方案 先决条件&#xff1a; 已经拥有含有GDAL的python环境&#xff08;如果大家需要&#xff0c;我可以后面出一片文章 问题一&#xff1a;QGIS连接到PostGIS数据库失败 错误描述&#xff1a; Connection to server at &quo…