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

【Linux】进程间通信 —— 管道

文章目录

  • 📕 进程间通信介绍
  • 📕 匿名管道
    • 原理
    • 使用
    • 读写规则
    • 特点
  • 📕 命名管道
    • 原理
    • 使用
    • 匿名管道和命名管道的区别

📕 进程间通信介绍

进程间通信,顾名思义,就是两个进程之间的 “交流” ,我们知道,进程是相互独立的,也就是说,正常情况下,两个进程之间无法传递消息,但是有时候又需要 进程间通信,如下,这是进程间通信的目的。

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

要达到这些目的,就需要使用一些技术来完成进程间通信。以下是三类技术,管道 、System V、POSIX 。本篇文章主要讲解管道的方法。

  • 管道
    • 匿名管道pipe
    • 命名管道
  • System V IPC
    • System V 消息队列
    • System V 共享内存
    • System V 信号量
  • POSIX IPC
    • 消息队列
    • 共享内存
    • 信号量
    • 互斥量
    • 条件变量
    • 读写锁

那么什么是管道呢?
管道是Unix中最古老的进程间通信的形式。我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”。

听起来很抽象,可以了解一下管道的原理,就明白了!

📕 匿名管道

原理

如下图,一个进程可以打开多个文件,其 file_struct 里面的文件描述符 0、1、2 分别指向了内存里的 三个 struct file,在文件描述符那篇文章有提到,每一个 struct file 都有对应的缓冲区,是内存级别的。(要理解这里的内容,首先要了解文件描述符哦,可以看一下这篇文章:【Linux】文件描述符)

所以,我们可以用操作系统创建管道的系统调用,打开一个文件(下图中绿色部分),分别以 读、写 方式打开(具体原因下文会讲),然后这个打开的文件会对应有 struct file 和 缓冲区。这些都是操作系统的行为,所以即使磁盘上没有对应的文件,也可以这样打开。当不需要使用管道的时候,直接将内存里的对应 struct file 和缓冲区释放即可。

所以,管道就是一个妥妥的内存级的文件!!

请添加图片描述

此时,我们再 fork() ,产生一个子进程,子进程会继承父进程的绝大多数内容,包括 file_struct ,但是子进程并不会创建新的文件,因为这是属于文件系统范畴了, fork() 只是创建子进程。此时,子进程同样地也以读写的方式打开了父进程创建的管道文件
请添加图片描述

然后,由于管道是半双工的,所以要在父子进程里面,一个关闭读端,一个关闭写端,就可以完成进程间通信的基本条件。
比如这里,我需要父进程写入信息,子进程读取父进程的信息,那么就把父进程的读端关闭,子进程的写端关闭,这样子就是父进程写、子进程读!

请添加图片描述

使用

创建匿名管道需要用到 pipe() 系统调用。

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

使用匿名管道需要注意几点,首先是要在创建子进程之前,创建管道。否则子进程无法继承父进程的文件描述符。
其次,不要忘记关闭读端或者写端。

#include <iostream>
#include <unistd.h>
#include <cerrno>
#include <string.h>
#include <stdio.h>using std::cout;
using std::endl;int main()
{int pipefd[2] = {0};// 1.创建管道int n = pipe(pipefd); // pipefd[0] 写端   pipefd[1] 读端if (n == -1){cout << "create pipe error," << errno << strerror(errno) << endl;exit(1);}// cout<<pipefd[0]<<endl<<pipefd[1];// 2.创建子进程pid_t pid = fork();// 子进程if (pid == 0){// 3.子进程写,那么关闭读端close(pipefd[0]);// 4.通信char buf[128];int cnt = 1;while (true){snprintf(buf, sizeof buf, "我是子进程,cnt:%d ,pid: %d\n", cnt++, getpid());write(pipefd[1], buf, strlen(buf));}close(pipefd[1]); // 管道声明周期随进程,所以不手动关闭,进程结束后也会自动关闭exit(1);}// 父进程// 3.父进程读,关闭写端close(pipefd[1]);// 4.通信char buf[128];while (true){sleep(3);int n = read(pipefd[0], buf, sizeof(buf) - 1); // 留出一个位置放\0if (n > 0){buf[n]='\0';cout << "我是父进程,子进程给的信息:" << buf << endl;}}close(pipefd[0]);return 0;
}

上面的 写入、读取 代码可以看出,写入速度快,读写数据慢。 写入了很多次,才读取一次。但是下图运行结果,并不是写入一次,就读取一次,而是可以写入多次,然后一次性读取。

从这里可以看出,读写不是强相关的。(这里指的是读写次数的多少)

请添加图片描述

读写规则

  • 如果读端读取了管道内的所有数据,而写端不写入,那么只能等待。
  • 如果写端将管道写满了,读端没有读取数据,那么就无法写入。
  • 如果写端关闭,读端依然打开,在读取完管道内剩余的数据之后,再次读取数据,则 read 返回0。
  • 如果读端关闭,而写端还向管道写入数据,毫无疑问这是没有意义的,操作系统不会运行这样的事情发送。所以,write 操作会产生信号SIGPIPE,进而可能导致write进程退出。

特点

  1. 单向通信(半双工)
  2. 管道的本质是文件,因为 fd 的生命周期随进程,所以管道的生命周期也是随进程的
  3. 管道通信,通常用来 对具有“血缘”关系的进程,进行进程间通信。常用于父子通信 – pipe 打开管道,并不清楚管道的名字(匿名管道)。
  4. 在管道通信中,写入的次数 和 读取的次数是不严格匹配的,读写次数的多少没有强相关,读取是按照字节流来读取的。
  5. 根据上面的读写规则,可以知道,管道具有一定的协同能力,能让 reader 和 writer 按照一定的步骤进行通信——自带同步机制。

📕 命名管道

原理

如下,一个进程打开了磁盘上的一个文件。当另一个进程(和之前的进程没有血缘关系),也打开同一个文件的时候,操作系统不会重新创建一个 struct file 对象,而是直接使用之前的。

那么,此时,两个进程就看到了同一个文件,也就可以进行进程间通信。
但是,如果这个文件是普通文件,那么数据会定期刷新的磁盘里。可是如果我们要进行进程间通信,数据就不应该被刷新到磁盘里面,而是在进程之间进行传输。所以,这就要求创建的文件是一个内存级别的文件,由此诞生了命名管道文件!不需要维护其 datablock,只需要告诉操作系统,这个文件存在!以后 两个进程可以打开这个文件,打开文件就会在内核匹配对应的缓冲区,所以两个进程就看到同一份资源!!

这个原理和上面匿名管道的原理其实是一样的!!
在这里插入图片描述

使用

命名管道可以从命令行上创建,命令行方法是使用下面这个命令:

  • $ mkfifo filename

命名管道也可以从程序里创建,相关函数有:

  • int mkfifo(const char *filename,mode_t mode);

如下是在程序里面实现命名管道,以及进程间通信。 server 进程和 client 进程进行交互。

comm.hpp 头文件

#pragma once#include<iostream>
#include<string>#define NUM 1024const std::string filename="./fifo";mode_t mode=0666;

server.cc 文件


#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include<fcntl.h>
#include <cerrno>
#include <cstring>
#include<unistd.h>#include"comm.hpp"using std::cin;
using std::cout;
using std::endl;int main()
{// 1.创建命名管道umask(0);int n = mkfifo(filename.c_str(),mode);if(n < 0){cout<<"create fifo error:"<<errno<<":"<<strerror(errno)<<endl;return 1;}cout<<"create fifo success"<<endl;// 2.开启管道文件int rfd=open(filename.c_str(),O_RDONLY);if(rfd < 0){cout<<"open fifo file error:"<<errno<<":"<<strerror(errno)<<endl;return 1;}cout<<"open fifo file success"<<endl;// 3. 开始通信char buf[NUM];while(true){// 先将缓冲区置0buf[0]=0;size_t n=read(rfd,buf,sizeof(buf)-1); // 读取是按字节流,所以去掉 \0if(n > 0){buf[n]='\0';cout<<"client#"<<buf<<endl;fflush(stdout);}else if(n==0){cout<<"client quit,i will quit either"<<endl;break;}else{cout<<errno<<":"<<strerror(errno)<<endl;}}close(rfd);unlink(filename.c_str());return 0;
}

client.cc 文件


#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <cerrno>
#include <cstring>
#include <unistd.h>
#include<cassert>#include "comm.hpp"using std::cin;
using std::cout;
using std::endl;int main()
{// 打开fifoint wfd=open(filename.c_str(),O_WRONLY);if(wfd < 0){cout<<"open fifo error"<<errno<<":"<<strerror(errno)<<endl;return 1;}cout<<"open fifo success"<<endl;// 写入char buf[NUM];while(true){cout<<"请输入你的信息#";char* msg=fgets(buf,sizeof(buf),stdin); // C库的函数,会默认加上 \0assert(msg);(void*)msg;size_t n=write(wfd,buf,sizeof(buf)-1);if(strcasecmp(buf,"quit") == 0) break;}close(wfd);return 0;
}

如下,server 是读端, client 是写端,只有 client 写入消息, server 才会读取,实现进程间通信。
如果单单在 server 写入消息, client 是不会读取的,因为 server是读端, client 是写端。
在这里插入图片描述

匿名管道和命名管道的区别

  • 匿名管道由pipe函数创建并打开。
  • 命名管道由mkfifo函数创建,打开用open
  • FIFO(命名管道)与pipe(匿名管道)之间唯一的区别在它们创建与打开的方式不同,一但这些工作完成之后,它们具有相同的语义。

相关文章:

【Linux】进程间通信 —— 管道

文章目录 &#x1f4d5; 进程间通信介绍&#x1f4d5; 匿名管道原理使用读写规则特点 &#x1f4d5; 命名管道原理使用匿名管道和命名管道的区别 &#x1f4d5; 进程间通信介绍 进程间通信&#xff0c;顾名思义&#xff0c;就是两个进程之间的 “交流” &#xff0c;我们知道&…...

知识管理在企业中的重要性

随着经济全球化和信息化的快速发展&#xff0c;企业面临着越来越多的竞争和挑战。如何把握市场动态、满足客户需求、提高产品质量和效率等&#xff0c;成为了企业发展中亟待解决的问题。而知识管理作为一种新兴的管理方式&#xff0c;逐渐引起了企业们的重视。本文将从以下几个…...

Socks5、网络安全、代理IP技术详解

随着互联网的发展&#xff0c;网络安全问题越来越受到人们的关注。为了保护个人隐私和网络安全&#xff0c;使用代理服务器成为了一种普遍的选择。其中&#xff0c;Socks5协议是一种常见的代理协议&#xff0c;而代理IP是使用代理服务器时经常需要考虑的问题。本文将深入探讨So…...

C++学习day--09 字符串比较、运算符

1、项目练习 第 1 节 项目需求、项目实现 项目实现&#xff1a; #include <iostream> #include <Windows.h> #include <string> using namespace std; int main( void ) { string name; string pwd; std::cout << " 请输入账号&am…...

缓存和数据库一致性问题

如何保证缓存和数据库一致性&#xff0c;这是一个老生常谈的话题了。 但很多人对这个问题&#xff0c;依旧有很多疑惑&#xff1a; 到底是更新缓存还是删缓存&#xff1f; 到底选择先更新数据库&#xff0c;再删除缓存&#xff0c;还是先删除缓存&#xff0c;再更新数据库&am…...

4月京东生鲜水果行业数据报告:榴莲销量增长400%,市场格局剧变

众所周知&#xff0c;今年水果领域的一个重磅消息就是&#xff1a;榴莲价格暴跌。目前全国多地线下水果专卖店、农贸市场的榴莲价格都在下滑&#xff0c;有的地区在4月底甚至已经降至最低每斤20元左右。预测在5月的销售旺季&#xff0c;价格还有望一路向下。 •榴莲逆袭苹果&am…...

Windows无法完成格式化怎么办?正确的3个解决方法!

案例&#xff1a;Windows无法完成格式化怎么办 【由于我的U盘使用时间过长&#xff0c;很多文件都是不需要的&#xff0c;我想将其格式化&#xff0c;但插入电脑后&#xff0c;Windows根本无法完成格式化&#xff0c;这是为什么呢&#xff1f;我应该怎么做呢&#xff1f;求答案…...

基于aspnet个人博客网站dzkf6606程序

系统使用Visual studio.net2010作为系统开发环境&#xff0c;并采用ASP.NET技术&#xff0c;使用C#语言&#xff0c;以SQL Server为后台数据库。 1&#xff0e;系统登录&#xff1a;系统登录是用户访问系统的路口&#xff0c;设计了系统登录界面&#xff0c;包括用户名、密码和…...

不黑艺术学社京藏行——参观五台山孙溟㠭为五台山红英师治印

不黑学社社长孙溟㠭先生与五台山菩萨顶主事红英师 不黑学社京藏行&#xff0c;路经五台把佛拜。 巍巍五台清凉境&#xff0c;参访伊始菩萨顶。 感恩“天珠”刘诗语&#xff0c;芬芳佛语满香华。 感恩慈悲红英师&#xff0c;带众参拜大白塔。 菩萨顶上如意宝&#xff0c;莲…...

mysql数据之表管理-mysql高级管理

1. #创建表tt01 #对id字段设置零填充约束、主键约束、自增长约束 #对name字段设置非空约束、默认值约束 #对cardid字段设置非空约束、唯一键约束 插入数据记录&#xff1a; 1&#xff09;因为id字段设置了自增长&#xff0c;如果不指定id字段值&#xff0c;则默认从1开始递…...

公司新来的00后真是卷王,工作没2年,跳槽到我们公司起薪18K都快接近我了

说00后躺平了&#xff0c;但是有一说一&#xff0c;该卷的还是卷。这不&#xff0c;前段时间我们公司来了个00后&#xff0c;工作都没两年&#xff0c;跳槽到我们公司起薪18K&#xff0c;都快接近我了。后来才知道人家是个卷王&#xff0c;从早干到晚就差搬张床到工位睡觉了。 …...

面试题30天打卡-day19

1、TCP 和 UDP 协议有什么区别&#xff0c;分别适用于什么场景&#xff1f; TCP&#xff08;Transmission Control Protocol&#xff09;和UDP&#xff08;User Datagram Protocol&#xff09;是两种常用的传输层协议&#xff0c;两者的区别比较如下&#xff1a; TCPUDP可靠性…...

ASEMI代理ADI亚德诺LTC6992IS6-1#TRMPBF车规级芯片

编辑-Z LTC6992IS6-1#TRMPBF参数描述&#xff1a; 型号&#xff1a;LTC6992IS6-1#TRMPBF 输出频率&#xff1a;3.81Hz 工作电源电压范围&#xff1a;2.25 - 5.5V 通电复位电压&#xff1a;1.95V 电源电流&#xff1a;105-365A SET引脚处的电压&#xff1a;1V 频率设置电…...

Oracle PL/SQL基础语法学习15:静态表达式

系列文章目录 Oracle PL/SQL基础语法学习12&#xff1a;短路求值 Oracle PL/SQL基础语法学习13&#xff1a;比较运算符 Oracle PL/SQL基础语法学习14&#xff1a;BOOLEAN表达式 文章目录 系列文章目录前言Oracle PL/SQL基础语法学习15&#xff1a;静态表达式Static Expression…...

B-Tree (多路查找树)分析-20230503

B-Tree (多路查找树)学习-20230503 前言 B-树是一类多路查询树&#xff0c;它主要用于文件系统和某些数据库的索引&#xff0c;如果采用二叉平衡树访问文件里面的数据&#xff0c;最坏情况下&#xff0c;磁头可能需要进行O(h)次对磁盘的读写&#xff0c;其中h为树的高度&…...

OpenGL光照教程之 透光物

引言 我们目前使用的所有光照都来自于一个单独的光源&#xff0c;这是空间中的一个点。它的效果不错&#xff0c;但是在真实世界&#xff0c;我们有多种类型的光&#xff0c;它们每个表现都不同。一个光源把光投射到物体上&#xff0c;叫做投光。这个教程里我们讨论几种不同的投…...

如何使用hook?

目标&#xff1a;将posix函数hook住 一个简单的例子 &#xff08;连接mysql服务&#xff09;&#xff0c;连接成功则打印success mysql.c #include <mysql/mysql.h> #include <stdio.h> int main(){MYSQL* mysql mysql_init(NULL);if(!mysql){printf("my…...

双指针技巧秒杀七道链表题目

文档阅读 文档阅读 题目 141. 环形链表 https://leetcode.cn/problems/linked-list-cycle/ public class Solution {public boolean hasCycle(ListNode head) {ListNode fast head, slow head;while(fast ! null && fast.next ! null){fast fast.next.next;slo…...

在“裸奔”时代保护我们的隐私:网络攻击、数据泄露与隐私侵犯的应对策略与工具

摘要&#xff1a;随着信息技术的普及和发展&#xff0c;个人隐私和数据安全问题日益受到威胁。本文将讨论如何有效应对网络攻击、数据泄露和隐私侵犯&#xff0c;并提供一系列实用的技巧和工具&#xff0c;以帮助我们在“裸奔”时代更好地保护数据安全和隐私。 当今社会&#…...

如何写出高质量代码

你是否曾经为自己写的代码而感到懊恼&#xff1f;你是否想过如何才能写出高质量代码&#xff1f;那就不要错过这个话题&#xff01;在这里&#xff0c;我们可以讨论什么是高质量代码&#xff0c;如何写出高质量代码等问题。无论你是初学者还是资深开发人员&#xff0c;都可以在…...

[oeasy]python0048_注释_comment_设置默认编码格式

注释Comment 回忆上次内容 使用了版本控制 git 制作备份进行回滚 尝试了 嵌套的控制结构 层层 控制 不过 除非 到不得以尽量不要 太多层次的嵌套 这样 从顶到底含义 明确而且 还扁平 扁平 也能 含义明确 还可以 做点什么&#xff1f; 让程序含义 更加明确呢&#xff1f;&…...

C++中的queue与priority_queue

文章目录 queuequeue的介绍queue的使用 priority_queuepriority_queue介绍priority_queue使用 queue queue的介绍 队列是一种容器适配器&#xff0c;专门用于上下文先进先出的操作中。队列的特性是先进先出&#xff0c;从容器的一端插入&#xff0c;另一端提取元素。   队列…...

电脑发挥极致,畅游永恒之塔sf

随着22寸显示器的普及&#xff0c;玩永恒之塔势必会对显示卡造成了很大负担。不要说效果全开&#xff0c;就连简洁的玩&#xff0c;都成了问题&#xff0c;那是不是就要重金把才买的显示卡又要拿掉呢&#xff1f; 最出众的解决办法&#xff0c;是超频。 主要就具有以下条件最佳…...

ChatGPT :十几个国内免费可用 ChatGPT 网页版

前言 ChatGPT&#xff08;全名&#xff1a;Chat Generative Pre-trained Transformer&#xff09;&#xff0c;美国OpenAI 研发的聊天机器人程序 &#xff0c;于2022年11月30日发布 。ChatGPT是人工智能技术驱动的自然语言处理工具&#xff0c;它能够通过理解和学习人类的语言…...

5 分钟教你如何免费用上 GPT-4

今天要分享的就是普通用户&#xff0c;没有 OpenAI 账号&#xff0c;不需要写代码&#xff0c;你依然可以免费体验 GPT-4&#xff0c;当然&#xff0c;会有一些缺点&#xff0c;本篇文章将会手把手教你怎么用上免费版的 GPT-4 以及它的一些限制。 第一步&#xff1a;打开 Stea…...

安卓手机搭建智能语音客服/通话播音/聊天播音乐技术实现

声明&#xff0c;此项技术需要root支持&#xff0c;如果因为刷机导致手机变砖或其他不可预料的后果请自行解决。 场景 我有一个朋友他是做业务的&#xff0c;主要还是做电销&#xff0c;其实电销相对于以前纪念没那么好做了&#xff08;我自己觉得主要是互联网冲击&#xff0c…...

【学习笔记】PKUSC2023 不知道咋记

挺快乐的。到 P K U PKU PKU感受了一下北大校园&#xff0c;其实并没有想像中那么令人惊艳&#xff0c;但是看到了许多亲切的学长以及他们的热心陪伴&#xff08;虽然有的我甚至不认识&#xff09;&#xff0c;感觉心里还是挺暖的。 如果不算上 D 2 T 1 D2T1 D2T1被平衡树板子…...

Packet Tracer - 配置基于区域的策略防火墙 (ZPF)

Packet Tracer - 配置基于区域的策略防火墙 (ZPF) 拓扑图 地址分配表 设备 接口 IP 地址 子网掩码 默认网关 交换机端口 R1 G0/1 192.168.1.1 255.255.255.0 不适用 S1 F0/5 S0/0/0 (DCE) 10.1.1.1 255.255.255.252 不适用 不适用 R2 S0/0/0 10.1.1.2 255…...

全方位揭秘!大数据从0到1的完美落地之运行流程和分片机制

一个完整的MapReduce程序在分布式运行时有三类实例进程&#xff1a; MRAppMaster: 负责整个程序的过程调度及状态协调MapTask: 负责Map阶段的整个数据处理流程ReduceTask: 负责Reduce阶段的整个数据处理流程 当一个作业提交后(mr程序启动)&#xff0c;大概流程如下&#xff1…...

后端程序员的前端必备【Vue】 - 07 ES6新语法

ES6新语法 1 let定义变量2 const定义常量3 模板字符串4 方法默认值5 箭头函数6 解构6.1 对象解构6.2 数组解构6.2 使用解构实现变量交换 7 Spread Operator8 模块化编程 1 let定义变量 使用let定义变量能更加精准的确定变量的作用域 //for(var i 0 ; i < 10 ; i){} for(let…...

成全视频观看高清在线观看/北京seo网站推广

一、电脑软硬件基础知识1、CPU型号怎么看&#xff1f;CPU是一台电脑的核心&#xff0c;而目前笔记本市场基本被Intel(英特尔)的CPU垄断。而Intel的CPU型号命名还算比较有规律。以i7-6920HQ为例&#xff1a;四位数的头一个数字是6指的是代际&#xff0c;也就是是英特尔第六代处理…...

如何快速建设自适应网站/深圳网络营销策划

本节书摘来自华章计算机《大数据架构和算法实现之路&#xff1a;电商系统的技术实战》一书中的第2章&#xff0c;第2.4节&#xff0c;作者 黄 申&#xff0c;更多章节内容可以访问云栖社区“华章计算机”公众号查看。 2.4 案例实践 2.4.1 使用R进行K均值聚类 在实践部分&…...

计算机网站建设相关的书籍/重庆seo整站优化外包服务

出处&#xff1a;http://blog.sina.com.cn/s/blog_7db333fb010132it.html转载于:https://www.cnblogs.com/mq0036/p/4747648.html...

做游戏ppt下载网站有哪些内容/直销的八大课程

绑定两台路由器之间的多条E1链路的方法有如下几种1.硬件IMUX 2-82.ATM IMA 2-323.Multilink ppp 2-84.Load balancing 2-6其中1、2为硬件解决方式&#xff0c;3、4为软件解决方式 PPP multilink配置方法&#xff1a;interface Mu…...

不用开源做网站/抖音代运营大概多少钱一个月

修改当前路径&#xff0c;但是一重启就恢复原样export PATH/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/games 例如&#xff1a;该路径忘记加&path了 ubuntu命令行界面/bin/echo $PATH (查看当前启动路径) cat /etc/profile (查…...

原创wordpress主题/太原最新情况

games101_光线追踪4上节内容Monte Carlo Integration(蒙特卡洛积分)采样举例Path Tracing(路径追踪)Whitted-Style光线追踪产生的错误问题一&#xff1a;The Utah Teapot问题二&#xff1a;The Cornell BoxWhitted-Style光线追踪是错误的蒙特卡洛方法对于一个采样点的解决方法问…...