Linux---进程间通讯(上)

一、进程间通讯的目的

  • 数据传输:一个进程需要将它的数据发送给另一个进程
  • 资源共享:多个进程之间共享同样的资源。
  • 通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。
  • 进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变

进程间通讯的本质:让不同的进程看到同一份资源(一般由OS提供),以此保证进程的独立性

二、进程间通信分类

  • 管道:1.匿名管道     2.命名管道
  • System V IPC:1.System V 消息队列  2.System V 共享内存   3.System V 信号量
  • POSIX IPC:1.消息队列   2.共享内存   3.信号量   4.互斥量   5.条件变量   6.读写锁

三、 管道

管道的4种情况

1、如果管道没有数据了,读端必须等待,直到有数据为止(写端写入数据)

2、如果管道被写满了,写端必须等待,直到有空间为止(读端读走数据)

3、写端关闭,读端一直读,读端会读到文件的结尾,read返回值为0

4、读端关闭,写端一直写,OS会直接杀掉写端进程,通过向目标进程发送SIGPIPE(13)

管道的5种特性

1.匿名管道,可以允许具有血缘关系的进程之间进行通信,常用于父子,仅限于此,即没有血缘关系的进程无法用匿名管道进行通信

2.匿名管道,默认给读写端要提供同步的机制

3.面向字节流的

4.管道的生命周期随进程的,即进程结束,管道会自动关闭,当然手动关闭也行

5.管道是单向通信

注意:读端和写端必须同时被打开,不然两个进程会相互等待,直到双方都打开为止

如何理解管道的同步机制?这个目前可以理解为两个进程的通信大体上呈现出一种回合制的感觉,即写一句,读一句 / 写完了之后开始读 / 管道写满了,读出一些,然后再写,然后再读....

如何理解面向字节流?这个目前可以理解为我们的数据是以字节为单位进行传输的,就比如我们传一个int类型的整数,在读取的时候可以读出一个int类型的整数,也可以读出4个char类型的字符

1、匿名管道

1、指令级的使用

我们在命令行上敲的 | 就是对匿名管道的使用

通过上面这个简单的例子,我们就能看出匿名管道是在有血缘关系的进程间进行通信的(上面的命令只是为了验证这一点,并没有啥特别的作用) 

2、代码级的使用 

 #include <unistd.h>
功能:创建一无名管道
原型
int pipe(int fd[2]);
参数
fd:文件描述符数组,其中fd[0]表示读端,fd[1]表示写端
返回值:成功返回0,失败返回错误代码

函数原理如下

使用方法如下

#include <unistd.h>
#include <iostream>
#include <cassert>
#include <cstring>
#include <sys/types.h>
#include <sys/wait.h>
#include <cstdlib>
#include <cstdio>
using namespace std;#define MAX 1024
int main()
{//1、建立管道int pipefd[2] = {0};int n = pipe(pipefd);assert(n == 0);//cout<<pipefd[0]<<" "<<pipefd[1]<<endl;cout << "I am father ,pid:" << getpid() << endl;//2、创建子进程pid_t id = fork();if(id < 0){perror("fork");return -1;}char buffer[MAX] = { 0 };//3、关闭多余的fd,形成单向通信//父读,子写if(id == 0)//子进程{close(pipefd[0]);char message[MAX] = { 0 };int cnt = 0;while(1){snprintf(message, MAX, "hello father, my pid:%d, cnt:%d", getpid(), cnt++);write(pipefd[1], message, strlen(message));cout << "writing ..." << endl;}// close(pipefd[1]);//可以手动关闭写端,也可以等进程结束,让OS帮你关闭exit(0);}//父进程close(pipefd[1]);while(true){ssize_t n = read(pipefd[0], buffer, sizeof(buffer) - 1);//如果写端没有关闭,管道中没有数据会在这里阻塞,如果写端关闭,将管道中的数据读完就会返回0if(n > 0){cout << "child say:" << buffer << endl;}else if(n == 0){cout << "read end" << endl;break;}}close(pipefd[0]);pid_t ret = waitpid(id, nullptr, 0);if(ret == id){cout<<"wait success"<<endl;}return 0;
}

(对于匿名管道的4种情况和一些特性,有兴趣可以在自己的电脑上验证一下,这里就不演示了,想验证啥就在上面的代码上进行适当修改即可)

2、命名管道

1、指令级的使用

简单演示一下用法

2、代码级的使用

代码如下

//shared.h
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#define FILENAME ".fifo"//server.cc
#include "shared.h"
bool Makefifo()
{int n = mkfifo(FILENAME,0666);if(n < 0){std::cout << "errno: " << errno << ",errstring: " << strerror(errno) << std::endl;return false;}return true;
}int main()
{
Start:int rfd = open(FILENAME, O_RDONLY);if(rfd < 0){std::cout << "open failed" << std::endl;if(Makefifo()) goto Start;else return 0;}char buffer[1024] = { 0 };while(1){ssize_t n = read(rfd, buffer, sizeof(buffer)-1);if(n > 0){buffer[n] = 0;//添加\0std::cout << "Client say# "<< buffer << std::endl;}else if(n == 0){std::cout << "Client quit, sercer quit too!" << std::endl;break;}}return 0;
}//client.cc
#include "shared.h"
int main()
{int wfd = open(FILENAME, O_WRONLY);if(wfd < 0){std::cout << "open failed" << std::endl;return 0;}std::string message;while(1){std::getline(std::cin,message);write(wfd, message.c_str(), message.size());} return 0;
}

总结:管道这种通信方式本质就是在复用文件相关的函数,没有啥新的知识点,在一定层度上说明复用的强大(新瓶装旧酒还是很管用的)

ulimit   用来设置和查看系统资源限制,如下

从上面这张图我们也能看出管道文件的大小为512*8=4096字节,但是实际上不是,感兴趣的可以去测试一下自己的管道文件的大小,测试方法:写端边写边打印次数,每次写入1个字节的数据,读端sleep(较大的数),直到写满为止,看打印了多少次

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

聚观早报 | OPPO公布全新AI战略;华为P70 Art影像细节曝光

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 2月22日消息 OPPO公布全新AI战略 华为P70 Art影像细节曝光 苹果正加速开发智能戒指 微软将大规模投资人工智能 …

ArcgisForJS如何访问Arcgis Server?

文章目录 0.引言1.准备ArcGIS相关工具2.创建含有ArcSDE地理数据库的MXD文件3.注册ArcSDE地理数据库4.发布数据到Arcgis Server5.ArcgisForJS访问ArcGIS Server数据 0.引言 ArcGIS API for JavaScript 是一个用于在Web和移动应用程序中创建交互式地图和地理空间分析应用的库。它…

[word] 如何使用Excel制作简单的流程图 #媒体#微信#学习方法

如何使用Excel制作简单的流程图 对于在职场办公的朋友们来说&#xff0c;经常要使用到Excel演示公式&#xff0c;制作各种图表等等&#xff0c;其实Excel还可以制作简单的流程图呢&#xff0c;估计许多小伙伴们还不知道吧&#xff0c;今天就来给大家演示一下&#xff0c;看完就…

在VSCode中新配置一个ros项目

如何从零开始配置一个ros项目 预先准备初始化ros工程运行hello_ros进行第一个示例进行编译测试 预先准备 首先要在vscode中安装&#xff08;必须安装的&#xff09;&#xff1a;ros&#xff0c;c&#xff0c;cmake&#xff0c;cmake tools&#xff08;补全camkelist文件&#…

一个C#开发的大小只有8KB的贪吃蛇开源游戏!

大家好&#xff0c;我是编程乐趣。 今天给大家推荐基于C#开发的、一个贪吃蛇开源项目&#xff0c;这个项目除了实现贪吃蛇的功能外&#xff0c;重点是讲解如何把编译后的程序&#xff0c;从65MB精简为8KB。 项目地址 https://github.com/MichalStrehovsky/SeeSharpSnake 编译…

openssl3.2 - 编译 - zlib.dll不要使用绝对路径

文章目录 openssl3.2 - 编译 - 编译时的动态库zlib.dll不要使用绝对路径概述测试zlib特性在安装好的目录中是否正常笔记70-test_tls13certcomp.t80-test_cms.t对测试环境的猜测从头再编译测试安装一次测试一下随便改变位置的openssl用到zlib时是否好使测试一下随便改变位置的op…

为全志D1开发板移植LVGL日历控件和显示天气

利用TCP封装HTTP包请求天气信息 Linux还真是逐步熟悉中&#xff0c;现在才了解到Linux即没有原生的GUI&#xff0c;也没有应用层协议栈&#xff0c;所以要实现HTTP应用&#xff0c;必须利用TCP然后自己封装HTTP数据包。本篇即记录封装HTTP数据包&#xff0c;到心知天气请求天气…

javaSE多态

文章目录 斜体样式1.1 面向对象三大特征 ?1.2 什么是多态 ?*斜体样式*1.3 多态的前提1.4 多态的成员访问特点1.5 多态的优缺点1.6 多态的转型1.7 多态的转型注意1.8 解决转型安全隐患 2 内部类2.1 内部类的分类什么是内部类 ?什么时候使用内部类 ?内部类分类 ? 2.2 成员内…

【医学大模型】大模型 + 长期慢病的预测和管理

大模型 长期慢病的预测和管理 提出背景长期慢病框架慢性疾病检测框架如何实现多提示工程为什么使用多提示 慢性疾病管理框架个性化提示工程医学知识注入 提出背景 论文&#xff1a;https://arxiv.org/abs/2401.12988 慢性疾病是指那些需要长期管理和治疗的疾病&#xff0c;包…

PyTorch深度学习实战(37)——CycleGAN详解与实现

PyTorch深度学习实战&#xff08;37&#xff09;——CycleGAN详解与实现 0. 前言1. CycleGAN 基本原理2. CycleGAN 模型分析3. 实现 CycleGAN小结系列链接 0. 前言 CycleGAN 是一种用于图像转换的生成对抗网络(Generative Adversarial Network, GAN)&#xff0c;可以在不需要配…

车灯裂了用什么胶修复?

当车灯出现裂缝、破口、缺损、裂痕、破裂、破损、崩角、掉角等问题时&#xff0c;可以使用车灯无痕修复专用UV胶进行修复。车灯无痕修复专用UV胶是一种经过处理的UV树脂胶&#xff0c;主要成份是改性丙烯酸UV树脂。应用在车灯的专业无痕修复领域。 具有如下特点&#xff1a; 1…

详细描述一下CrossOver2024版本的用途和作用?

当然可以。CrossOver 是一款由 CODE WEAVERS 公司开发的软件&#xff0c;其主要目标是在 macOS 和 Linux 系统上实现与 Windows 应用程序的兼容性。它不同于传统的虚拟机&#xff0c;如 Parallels 或 VMware&#xff0c;因为它并不在 macOS 上创建一个完整的 Windows 环境。相反…

基于机器学习的青藏高原高寒沼泽湿地蒸散发插补研究_王秀英_2022

基于机器学习的青藏高原高寒沼泽湿地蒸散发插补研究_王秀英_2022 摘要关键词 1 材料和方法1.1 研究区概况与数据来源1.2 研究方法 2 结果和分析2.1 蒸散发通量观测数据缺省状况2.2 蒸散发与气象因子的相关性分析2.3 不同气象因子输入组合下各模型算法精度对比2.4 随机森林回归模…

安卓系统签名方法

首先在源码中创建key目录用来存放我们需要的文件&#xff0c;一般需要build/target/product/security/platform.pk8&#xff0c;build/target/product/security/platform.x509.pem&#xff0c;然后执行命令openssl pkcs8 -inform DER -nocrypt -in platform.pk8 -out platform.…

9.vue学习笔记(组件传递Props校验+组件事件-组件传递数据+组件事件-配合“v-model”使用)

文章目录 1.组件传递Props校验1.1.默认值1.2.必选项1.3.注意事项&#xff1a;props 是只读的 2.组件事件-组件传递数据2.1.温馨提示&#xff1a;组件之间传递数据的方案 3.组件事件-配合“v-model”使用 1.组件传递Props校验 Vue组件可以更细致地声明对传入的 props 的校验要求…

重铸安卓荣光——复选框ButtonCheckBox

痛点&#xff1a; 公司打算做安卓软件&#xff0c;最近在研究安卓&#xff0c;打算先绘制样式 研究发现安卓并不像前端有那么多组件库&#xff0c;甚至有些基础的组件都需要自己实现&#xff0c;记录一下自己实现的组件 成品展示 一个复选框样式 选中时背景橙色&#xff0c;带…

升级到PHP8.X的原因和方法

上周有一个使用Hostease美国主机服务器多年的客户&#xff0c;反馈需要升级到PHP8.x&#xff0c;原因是站点程序已升级&#xff0c;并希望站点运行在更高也稳定的PHP8.x上。在升级PHP8.x的过程中&#xff0c;联系我们并反馈在升级过程中遇到了问题&#xff0c;需求解决方案。 升…

利用LaTex批量将eps转pdf、png转eps、eps转png、eps转svg

1、eps转pdf 直接使用epstopdf命令&#xff08;texlive、mitex自带&#xff09;。 在cmd中进入到eps矢量图片的目录&#xff0c;使用下面的命令&#xff1a; for %f in (*.eps) do epstopdf "%f" 下面是plt保存eps代码&#xff1a; import matplotlib.pyplot as…

新手学习Cesium的几点建议

Cesium是当前非常火热的三维数字地球开发框架&#xff0c;很多公司基于Cesium做项目以及形成了自己的产品&#xff0c;关于Cesium的学习&#xff0c;有诸多网站、书籍、学习资料甚至培训教材&#xff0c;这里不再详细推荐&#xff0c;从学习Cesium的角度&#xff0c;资料和教程…

Android14 InputManager-InputReader的处理

IMS启动时会调用InputReader.start()方法 InputReader.cpp status_t InputReader::start() {if (mThread) {return ALREADY_EXISTS;}mThread std::make_unique<InputThread>("InputReader", [this]() { loopOnce(); }, [this]() { mEventHub->wake(); });…