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.mzph.cn/news/693465.shtml

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

相关文章

分享10款自媒体人常用ai写作工具,总有一款适合你 #其他#AI写作

你是否因为写作困顿而感到沮丧&#xff1f;是不是希望能够找到一个能给你提供无限灵感和提高创作效率的利器&#xff1f;AI写作助手就是你的绝佳选择&#xff01;现在我向大家推荐几款好用的AI写作助手&#xff0c;它们将让你的创作之旅更加流畅、富有创意。 1.七燕写作 这是一…

十二、通过色彩空间转换进行更换图片背景

项目功能实现&#xff1a;对一张白色背景的图片进行更换成蓝色背景&#xff0c;类似抠图更换背景操作 按照之前的博文结构来&#xff0c;这里就不在赘述了 一、头文件 inrange.h #pragma once#include<opencv2/opencv.hpp>using namespace cv;class INRANGE{ public:v…

华为OD机试真题-围棋的气-2023年OD统一考试(C卷)---python代码

题目&#xff1a; 代码&#xff1a; """ # 输入&#xff1a;2的倍数 第一个为行号 0-18 第二个为列号 0-18第一行为黑色 第二行为白色思路&#xff1a;先求黑色&#xff0c;进行去重棋子的位置&#xff0c;再求白色 逐个棋子求坐标。 """ d…

OpenLayers6入门,如何销毁已经创建好的OpenLayers地图容器

专栏目录: OpenLayers入门教程汇总目录 前言 本章介绍如何销毁已经创建好的OpenLayers地图容器。 在某些场景下,可能会需要销毁之前的地图,重新创建新的地图的需要,因此本章介绍一下在开始创建地图前如何先销毁之前的地图的功能。 二、依赖和使用 "ol": &qu…

用CSS3画一个三角形

<style> .up{width:0;height:0;border: 100px solid transparent;border-top: 100px solid red;/*红色*/ } .down{width:0;height:0;border: 100px solid transparent;border-bottom: 100px solid blue;/*蓝色*/ } .left{width:0;height:0;border: 100px solid transpare…

【爬虫JS逆向-工具篇】浏览器内存漫游加密参数Hook实战教程

文章目录 1. 写在前面2. 环境搭建2. 加密定位实战 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&#xff01; 【作者推荐】&#xff1a;对JS逆向感兴趣的朋友可以关…

JWT 重点讲解

JWT 重点讲解 文章目录 JWT 重点讲解1. JWT 是什么2. JWT 的组成2.1 第一部分 HEADER2.2 第二部分 PAYLOAD2.3 第三部分 SIGNATURE 3. JWT 在线生成与解析4. JWT 的特点4.1 无状态4.2 可自定义4.3 扩展性强4.4 调试性好4.5 安全性取决于密钥管理4.6 无法撤销4.7 需要缓存到客户…

Java集合框架-1

目录 List集合 常见方法 迭代器&#xff08;Iterator&#xff09; List集合特有方法 List 的特点 创建 List 遍历List Java集合框架是Java编程语言提供的各种数据结构和算法的实现。它提供了不同类型的集合类&#xff0c;如列表(List)、集(Set)、映射(Map)等&#xff0c…

一个获取正定矩阵的非常好的方法 (多元二次函数 ---> 正定矩阵) (done)

参考视频&#xff1a;https://www.bilibili.com/video/BV11T4y1S7YF/?spm_id_from333.337.search-card.all.click&vd_source7a1a0bc74158c6993c7355c5490fc600 如下图&#xff0c;是一种非常直接的获取正定矩阵的方法 &#xff08;且这种方法一定会获得对称矩阵&#xff…

IDEA 2023.2 配置 JavaWeb 工程

目录 1 不使用 Maven 创建 JavaWeb 工程 1.1 新建一个工程 1.2 配置 Tomcat 1.3 配置模块 Web 2 使用 Maven 配置 JavaWeb 工程 2.1 新建一个 Maven 工程 2.2 配置 Tomcat &#x1f4a5;提示&#xff1a;IDEA 只有专业版才能配置 JavaWeb 工程&#xff0c;若是社区版&am…

☀️将大华摄像头画面接入Unity 【2】配置Unity接监控画面

一、前言 上一篇咱们将大华摄像头接入到电脑上了&#xff0c;接下来准备接入到unity画面。 接入到监控就涉及到各种视频流的格式rtsp、rtmp、m3u8。 Unity里有一些播放视频流的插件&#xff0c;主要的就是AVPro Video 和 UMP等&#xff0c;这次我用的是UMP 最好使用2.0.3版本…

从0到1的私域流量体系搭建,私域操盘手的底层认知升级

一、教程描述 本套私域操盘手教程&#xff0c;大小4.31G&#xff0c;共有12个文件。 二、教程目录 01第一课、私域能力必修&#xff1a;私域大神熟记于心的高阶私域体系.mp4 02第二课、私域IP打造&#xff1a;那些忍不住靠近的私域IP如何打造的.mp4 03第三课、朋友圈经济&…

论文阅读——SqueezeSAM

SqueezeSAM: User-Friendly Mobile Interactive Segmentation 比SAM更小&#xff0c;更快。 框架&#xff1a; 使用的U型结构 使用BatchNorm而不是LayerNorm节省计算&#xff1b; 对于用户点击和框&#xff0c;单独作为通道&#xff0c;前融合和后融合&#xff08;sam只有后融…

OpenGL学习——16.多光源

前情提要&#xff1a;本文代码源自Github上的学习文档“LearnOpenGL”&#xff0c;我仅在源码的基础上加上中文注释。本文章不以该学习文档做任何商业盈利活动&#xff0c;一切著作权归原作者所有&#xff0c;本文仅供学习交流&#xff0c;如有侵权&#xff0c;请联系我删除。L…

OAuth2.0 最简向导

本文是一篇关于OAuth2.0的启蒙教程&#xff0c;图文并茂&#xff0c;通俗易懂&#xff0c;力求用最简洁明了的方式向初学者解释OAuth2.0是什么。本文并不是冗杂难懂的长篇大论&#xff0c;一图胜千言&#xff0c;深入浅出OAuth2.0&#xff0c;知其然知其所以然。 参考文献 首…

快速上手Spring Boot整合,开发出优雅可靠的Web应用!

SpringBoot 1&#xff0c;SpringBoot简介1.1 SpringBoot快速入门1.1.1 开发步骤1.1.1.1 创建新模块1.1.1.2 创建 Controller1.1.1.3 启动服务器1.1.1.4 进行测试 1.1.2 对比1.1.3 官网构建工程1.1.3.1 进入SpringBoot官网1.1.3.2 选择依赖1.1.3.3 生成工程 1.1.4 SpringBoot工程…

JAVA工程师面试专题-JVM篇

目录 一、运行时数据区 1、说一下JVM的主要组成部分及其作用? 2、说一下 JVM 运行时数据区 ? 3、说一下堆栈的区别 4、成员变量、局部变量、类变量分别存储在什么地方? 5、类常量池、运行时常量池、字符串常量池有什么区别? 6、JVM为什么使用元空间替换永久代 二、…

代码随想录算法训练营29期|day57 任务以及具体安排

第九章 动态规划part14 1143.最长公共子序列 /*二维dp数组 */ class Solution {public int longestCommonSubsequence(String text1, String text2) {// char[] char1 text1.toCharArray();// char[] char2 text2.toCharArray();// 可以在一開始的時候就先把text1, text2 轉成…

week04day01(爬虫)

一. 爬虫 只爬取公开的信息&#xff0c;不能爬取未公开的后台数据 1.爬虫的合法性 法无禁止皆可为 -- 属于法律的灰色地带https://www.tencent.com/robots.txt -- 网站/robots.txt 可以查看禁止爬取的内容 2. URL Uniform Resource Locator 统一资源定位符https://www.…

ACL权限-访问控制列表

一、简介 ACL&#xff08;access control list&#xff09;访问控制列表&#xff0c;可以对单一的用户或者组设置对文件或目录的独立rwx权限。 二、文件系统是否支持ACL权限 ACL权限是传统的Unix-like操作系统权限的额外支持项目&#xff0c;要有文件系统的支持&#xff0c;目前…