Linux进程间通信之管道

进程间通信介绍:

进程间通信的概念:

进程间通信简称IPC(Interprocess communication),进程间通信就是在不同进程之间传播或交换信息。

进程间通信的目的:

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

进程间通信的本质:

进程间通信的本质就是让不同的进程看到同一份资源。

进程间通信的发展:

管道
System V进程间通信
POSIX进程间通信

进程间通信的分类: 

管道

  • 匿名管道
  • 命名管道

System V IPC

  • System V 消息队列
  • System V 共享内存
  • System V 信号量

POSIX IPC

  • 消息队列
  • 共享内存
  • 信号量
  • 互斥量
  • 条件变量
  • 读写锁

管道:

认识管道:

由于进程间具有独立性,想要实现进程间通信非常困难,想要实现进程间通信就必须借助第三方资源,让两个需要通信的进程都可访问这个第三方资源,早期管道就是这样的第三方资源来实现进程间通信。

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

演示:

先来介绍两个命令:

1.who

who指令可以用来显示当前云服务器登录的用户数,一行显示一个用户。

如图所示现在有2个用户。 

 2.wc

wc指令可以查指定文件的计算文件的Byte数、字数、或是列数,若不指定文件名称、或是所给予的文件名为"-",则wc指令会从标准输入设备读取数据

wc加上-l指令,计算指定文件的行数。

将上述两个命令通过管道连接,就可以更准确地查出当前云服务器的登录用户:

who进程将数据写入管道,wc从管道中读取到数据,-l指令计算数据的行数,从而得出当前云服务器的登录数。 

匿名管道:

匿名管道性质: 

匿名管道仅支持父子间进程通信。

当我们创建一个进程,在linux系统中它被如下图进行管理:

我们再通过这个进程创建一个子进程,子进程继承父进程的代码和数据:

 没错,此时我们的父子进程能看到同一份资源,我们可以模拟一下通信,父进程往缓冲区写入,子进程往缓冲区读取,早期的工程师发现了这种现象,并且认为这是一种很好的进程间通信的方法,就在这种方法的基础上进行了一下改动,创造了管道。

注意:

我们在进程间通信时,是没必要对磁盘中的文件进行操作的,所以我们的管道没必要与磁盘中的文件产生关联。

文件级缓冲区是由操作系统来维护的,所以当父进程对其写入时,是不会发生写时拷贝的。

pipe函数:

int pipe(int pipefd[2]);

 pipe函数的参数是一个输出型参数,数组pipefd中的两个元素分别用来返回管道读端和写端的文件描述符:

数组元素含义
pipefd[0]管道读端文件描述符
pipefd[1]管道写端文件描述符

 匿名管道的使用:

注意下图中的fd均指pipefd。

1.父进程用pipe函数创建管道。

2.父进程通过fork函数创建子进程。

3.假设我们让子进程写,父进程读,所以我们要关闭不用的文件描述符,父进程关闭写端,子进程关闭读端。

 我们再站在文件描述符的角度深入理解:

匿名管道测试: 

现在用下述代码测试匿名管道,父进程进行一直读取,子进程进行一直写入:

#include <iostream>
#include <cerrno>
#include <cstring>
#include <string>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>const int size = 1024;//子进程进行写入
void SubProcessWrite(int wrd)
{std::string message = "father,i am your childen process! ";while(true){sleep(1);std::cout<<"childen begin write........."<<std::endl;static int cent = 0;pid_t id = getpid();//拼接消息std::string info = message;info += "my pid is ";info += std::to_string(id);info += ", cent: ";info += std::to_string(cent);//写入write(wrd,info.c_str(),info.size());cent++;}
}
//父进程进行读取
void FatherProcessReader(int rfd)
{char inbuffer[size];while(true){std::cout<<"father begin read,message:"<<std::endl;ssize_t n = read(rfd,inbuffer,sizeof(inbuffer) - 1);//读取消息if(n > 0){inbuffer[n] = 0;//语言限制,在字符串最后加\0std::cout<<inbuffer<<std::endl;//打印消息}}
}
int main()
{int pipefd[2];int n = pipe(pipefd);//管道创建成功,返回0if(n != 0)//管道创建失败{std::cerr<<"errno "<<errno<<"cerrstring: "<<strerror(errno)<<std::endl;}std::cout<<"读端->pipefd[0]"<<pipefd[0]<<"写端->pipefd[1]"<<pipefd[1]<<std::endl;sleep(1);pid_t id = fork();//创建子进程if(id == 0){//子进程进行写入std::cout<<"子进程关闭不需要的fd了,准备写消息了"<<std::endl;close(pipefd[0]);//关闭读端SubProcessWrite(pipefd[1]);//子进程写close(pipefd[1]);//任务完成关闭写端exit(0);}//父进程std::cout<<"父进程关闭不需要的fd了,准备读消息了"<<std::endl;close(pipefd[1]);//关闭写端FatherProcessReader(pipefd[0]);//父进程读close(pipefd[0]);//任务完成关闭读端pid_t rid = waitpid(id,NULL,0);//父进程等待子进程,并回收return 0;
}

来看看运行结果:

 管道的4种情况:

1.写端进程不写,读端进程一直读,那么此时会因为管道里面没有数据可读,对应的读端进程会被挂起,直到管道里面有数据后,读端进程才会被唤醒。


2.读端进程不读,写端进程一直写,那么当管道被写满后,对应的写端进程会被挂起,直到管道当中的数据被读端进程读取后,写端进程才会被唤醒。


3.写端进程将数据写完后将写端关闭,那么读端进程将管道当中的数据读完后,就会继续执行该进程之后的代码逻辑,而不会被挂起。


4.读端进程将读端关闭,而写端进程还在一直向管道写入数据,那么操作系统会将写端进程杀掉。

管道的大小:

管道是有容量的,当管道被写满了,写端将会阻塞或者失败,查询管道大小的方法有如下:

ulimit -a指令,查看当前资源限制。

从上图可以算出管道的大小为512*8 = 4096字节。 

命名管道:

刚才介绍的匿名管道,只可用于父子进程间通信,如果两个毫不相干的进程要实现通信该怎么办呢?接下来就需要介绍一下命名管道了。

mkfifo函数:

mkfifo函数用于创建一个命名管道。

mkfifo的第一个参数表示要创建的命令管道文件,如果不带路径默认再当前文件夹下。

mkfifo的第二个参数表示管道的文件权限。

例如文件权限设置为0666,则理论创建的管道权限为

 但实际文件权限还会受文件默认掩码umask影响,默认的umask是0002,我们实际的文件权限会先0666&(~umask),所以实际管道权限为0664:

mkfifo的返回值: 

管道创建成功返回0。

创建管道失败返回-1,错误码被设置。 

用命名管道实现serve&client通信

serve管理管道负责创建,销毁和读取消息,client负责往管道中写入消息:

serve.cc:

#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <cerrno>
#include <cstring>const std::string comm_name = "./myfifo";int main()
{//服务端创建命名管道int res = mkfifo(comm_name.c_str(),0666);if(res != 0)//创建失败{perror("mkfifo");}//serve端打开管道int fd = open(comm_name.c_str(),O_RDONLY);if(fd < 0){std::cout<<"open file"<<errno<<std::endl;}//serve接受消息并打印char buffer[1024];while(true){std::cout<<"server begin read:"<<std::endl;ssize_t n = read(fd,buffer,sizeof(buffer)-1);if(n > 0)//读取成功{buffer[n] = 0;std::cout<<buffer<<std::endl;}else if( n == 0){std::cout<<"read done"<<std::endl;break;}else{std::cout<<"read fail"<<errno<<std::endl;break;}}int n = unlink(comm_name.c_str());if(n != 0){perror("unlink");}return 0;
}

client.cc:

#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <cerrno>
#include <cstring>const std::string comm_name = "./myfifo";int main()
{//client以写打开管道int fd = open(comm_name.c_str(),O_WRONLY);if(fd < 0){std::cout<<"open fail"<<errno<<std::endl;}int cent = 100;sleep(5);while(cent--){sleep(1);std::cout<<"client begin write"<<std::endl;//消息拼接std::string message = "i sent a message ,cnet: ";message += std::to_string(cent);//写入消息ssize_t n = write(fd,message.c_str(),sizeof(message));}return 0;
}

来看看运行结果:

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

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

相关文章

血清素是怎么产生的,其过高和过低与我们情绪和胃肠健康有哪些关联?

谷禾健康 血清素&#xff0c;5-羟色氨(5-HT)不仅充当体内系统的神经递质和激素&#xff0c;而且还是胃肠系统中的旁分泌信使。 5-HT神经元系统起源于中脑中缝核&#xff0c;下面示意图强调了血清素(5-HT)神经元与释放不同神经递质的其他神经元以及神经胶质细胞之间的解剖相互作…

pxe自动装机

概念 pxe是c/s模式。允许客户端通过网络从远程服务器&#xff08;服务端&#xff09;下载引导镜像&#xff0c;加载安装文件&#xff0c;实现自动化安装操作系统。 无人值守&#xff1a;安装选项不需要人为干预&#xff0c;可以自动化实现。 pxe的优点&#xff1a;1.规模化&…

TqdmWarning: IProgress not found. Please update jupyter and ipywidgets.

jupyter notebook报错 在pycharm的terminal中 安装完成后就不会再报错了

经典神经网络(10)PixelCNN模型、Gated PixelCNN模型及其在MNIST数据集上的应用

经典神经网络(10)PixelCNN模型、Gated PixelCNN模型及其在MNIST数据集上的应用 1 PixelCNN PixelCNN是DeepMind团队在论文Pixel Recurrent Neural Networks (16.01)提出的一种生成模型&#xff0c;实际上这篇论文共提出了两种架构&#xff1a;PixelRNN和PixelCNN&#xff0c;两…

【排序算法】快速排序

文章目录 1.什么是快速排序2.快速排序的步骤3.时间复杂度 1.什么是快速排序 快速排序算法是一种高效的排序方法&#xff0c;它的基本思想是“分而治之”&#xff0c;通过一趟排序将待排记录分隔成独立的两部分&#xff0c;其中一部分记录的关键字均比另一部分的关键字小&#x…

从零开始手把手Vue3+TypeScript+ElementPlus管理后台项目实战五(引入vue-router,并给注册功能加上美丽的外衣el-form)

安装vue-router pnpm install vue-router创建router src下新增router目录&#xff0c;ruoter目录中新增index.ts import { createRouter, createWebHashHistory } from "vue-router"; const routes [{path: "/",name: "Home",component: () …

个人笔记-python生成gif

使用文件的修改时间戳进行排序 import os import re import imageio# 设置图片所在的文件夹路径 folder_path /home/czy/ACode/AMAW_20240219/9.3.x(Discrete_time_marching&#xff09;/9.3.17.11.1(Disc_concessive_CH_ZJ)/current_figures # 文件夹路径&#xff1b;linux…

网络编程: 高级IO与多路转接select,poll,epoll的使用与介绍

网络编程: 高级IO与多路转接select,poll,epoll的使用与介绍 前言一.五种IO模型1.IO的本质2.五种IO模型1.五种IO模型2.同步IO与异步IO3.IO效率 二.非阻塞IO1.系统调用介绍2.验证代码 三.select多路转接1.系统调用接口2.写代码 : 基于select的TCP服务器1.封装的Socket接口2.开始写…

前端 CSS 经典:水波进度样式

前言&#xff1a;简单实现水波进度样式&#xff0c;简单好看。 效果图&#xff1a; 代码实现&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"utf-8" /><meta http-equiv"X-UA-Compatible" cont…

《数学学习与研究》杂志是什么级别?知网收录吗?评职认可吗?

《数学学习与研究》杂志是什么级别&#xff1f;知网收录吗&#xff1f;评职认可吗&#xff1f; 《数学学习与研究》是由东北师范大学主管&#xff0c;吉林省数学会与东北师范大学出版社联合主办的省级优秀数学类期刊杂志。该杂志为半月刊&#xff0c;国际标准刊号为 ISSN1007-…

SkyWalking之P0业务场景输出调用链路应用

延伸扩展&#xff1a;XX业务场景 路由标签打标、传播、检索 链路标签染色与传播 SW: SkyWalking的简写 用户请求携带HTTP头信息X-sw8-correlation “X-sw8-correlation: key1value1,key2value2,key3value3” 网关侧读取解析HTTP头信息X-sw8-correlation&#xff0c;然后通过SW…

【Linux】系统优化:一键切换软件源与安装Docker

引言 在Linux系统安装完成后&#xff0c;进行一些必要的初始化设置是提升系统性能和用户体验的关键。本文将重点介绍两个实用的一键脚本&#xff1a;LinuxMirrors提供的软件源切换脚本和Docker安装脚本。这两个脚本将帮助我们简化配置安装过程。 一键切换软件源脚本 在Linux…

AI绘画如何打造高质量数据集?

遇到难题不要怕&#xff01;厚德提问大佬答&#xff01; 厚德提问大佬答11 你是否对AI绘画感兴趣却无从下手&#xff1f;是否有很多疑问却苦于没有大佬解答带你飞&#xff1f;从此刻开始这些问题都将迎刃而解&#xff01;你感兴趣的话题&#xff0c;厚德云替你问&#xff0c;你…

数据动态变化时实现多选及回显

<template><el-dialog title"设置权限" :visible.sync"showDialog" :close-on-click-modal"false" :append-to-body"true" width"800px"><div v-loading"loading"><el-radio-group v-model&…

【论文阅读】MODELING AND SOLVING THE TRAVELING SALESMAN PROBLEM WITH PRIORITY PRIZES

文章目录 论文基本信息摘要1.引言2. INTEGER QUADRATIC PROGRAM FOR TSPPP3. MIXED INTEGER LINEAR PROGRAMS FOR TSPPP4. TABU SEARCH ALGORITHM FOR TSPPP5. COMPUTATIONAL RESULTS6. CONCLUDING REMARKS补充 论文基本信息 《MODELING AND SOLVING THE TRAVELING SALESMAN P…

SQL语句练习每日5题(四)

题目1——查找GPA最高值 想要知道复旦大学学生gpa最高值是多少&#xff0c;请你取出相应数据 题解&#xff1a; 1、使用MAX select MAX(gpa) FROM user_profile WHERE university 复旦大学 2、使用降序排序组合limit select gpa FROM user_profile WHERE university 复…

【vuex小试牛刀】

了解vuex核心概念请移步 https://vuex.vuejs.org/zh/ # 一、初始vuex # 1.1 vuex是什么 就是把需要共享的变量全部存储在一个对象里面&#xff0c;然后将这个对象放在顶层组件中供其他组件使用 父子组件通信时&#xff0c;我们通常会采用 props emit 这种方式。但当通信双方不…

如何搭建一台永久运行的个人服务器?

一、前言 由于本人在这段时候&#xff0c;看到了一个叫做树莓派的东东&#xff0c;初步了解之后觉得很有意思&#xff0c;于是想把整个过程记录下来。 二、树莓派是什么&#xff1f; Raspberry Pi(中文名为树莓派,简写为RPi&#xff0c;(或者RasPi / RPI) 是为学习计算机编程…

38页 | 工商银行大数据平台助力全行数字化转型之路(免费下载)

【1】关注本公众号&#xff0c;转发当前文章到微信朋友圈 【2】私信发送 工商银行大数据平台 【3】获取本方案PDF下载链接&#xff0c;直接下载即可。 如需下载本方案PPT/WORD原格式&#xff0c;请加入微信扫描以下方案驿站知识星球&#xff0c;获取上万份PPT/WORD解决方案&a…

LlamIndex二 RAG应用开发

在AutoGen)系列后&#xff0c;我又开始了LlamIndex 系列。欢迎查询LlamaIndex 一 简单文档查询 - 掘金 (juejin.cn)了解LlamIndex&#xff0c;今天我们来看看LlamIndex的拿手戏&#xff0c;RAG应用开发。 何为RAG&#xff1f; RAG全称"Retrieval-Augmented Generation&q…