Linux系统---进程间通信与管道入门

news2024/11/24 17:07:13

顾得泉:个人主页

个人专栏:《Linux操作系统》 《C++从入门到精通》  《LeedCode刷题》

键盘敲烂,年薪百万!


一、进程间通信

1.进程间通信的目的

     1.数据传输:一个进程需要把他的数据传给另外一个进程。

     2.资源共享:多个进程之间共享同样的资源。

     3.通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。

     4.进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。

2.进程间通信发展

       最早的进程间通信方式是使用操作系统提供的共享内存和消息队列机制。共享内存允许多个进程将同一段内存映射到它们自己的地址空间,从而实现数据共享;消息队列则允许进程通过发送和接收消息来进行通信。

       随着网络技术的发展,进程间通信也逐渐向网络通信发展。网络通信使得不同计算机上的进程能够进行跨机器的通信和协作。常见的网络通信方式包括套接字(socket)、远程过程调用(RPC)和消息传递接口(MPI)等。

       近年来,随着多核处理器和分布式计算的普及,进程间通信的需求也越来越高。为了提高通信效率和方便编程,各种新的进程间通信技术应运而生。例如,管道(Pipe)和FIFO允许两个相关进程之间进行通信;信号量(Semaphore)和互斥锁(Mutex)等同步机制可以确保多个进程之间的正确协作;套接字和远程过程调用等技术允许分布在不同计算机上的进程进行通信。

3.进程间通信分类

管道

     1.匿名管道pipe

     2.命名管道

System V IPC

     1.System V 消息队列

     2.System V 共享内存

     3.System V 信号量

POSIX IPC

     1.消息列队

     2.共享内存

     3.信号量

     4.互斥量

     5.条件变量

     6.读写锁


二、管道

1.管道简介

       在Linux中,管道(pipeline)是一种机制,用于将一个命令的输出作为另一个命令的输入。通过使用管道,可以将多个命令组合在一起,以便实现更复杂的操作。

       在命令行中,使用竖线符号( | )来表示管道。

2.匿名管道

#include <unistd.h>

功能:创建一无名管道

原型

int pipe(int fd[2]);

参数

fd:文件描述符数组,其中fd[0]表示读端, fd[1]表示写端

返回值:成功返回0,失败返回错误代码

实例代码:

       从键盘读取数据,写入管道,读取管道,写到屏幕

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main( void )
{
    int fds[2];
    char buf[100];
    int len;
    if ( pipe(fds) == -1 )
    perror("make pipe"),exit(1);
    // read from stdin
    while ( fgets(buf, 100, stdin) ) 
    {
        len = strlen(buf);
        // write into pipe
        if ( write(fds[1], buf, len) != len ) 
        {
            perror("write to pipe");
            break;
        }
        memset(buf, 0x00, sizeof(buf));
        
        // read from pipe
        if ( (len=read(fds[0], buf, 100)) == -1 ) 
        {
            perror("read from pipe");
            break;
        }
        // write to stdout
        if ( write(1, buf, len) != len ) 
        {
            perror("write to stdout");
            break;
        }
    }
}

3.用fork来共享管道原理

       fork系统调用会在父进程中创建一个新的子进程,这个子进程与父进程几乎完全相同,包括代码段、数据段和堆栈段。这意味着子进程可以继承父进程的打开文件描述符等资源。

       在使用fork创建子进程后,父进程和子进程可以通过管道来进行通信。管道是一种特殊的文件,它能够连接一个进程的输出和另一个进程的输入。在Linux中,管道可以通过pipe系统调用来创建。

       当父进程创建管道后,它可以使用fork来创建子进程。接下来,父进程可以关闭管道的读端,子进程可以关闭管道的写端。这样,父进程就可以将数据写入管道的写端,子进程可以从管道的读端读取数据。

具体操作如下:

     1.父进程使用pipe系统调用创建一个管道。

     2.父进程使用fork系统调用创建子进程。

     3.子进程关闭管道的写端。

     4.父进程关闭管道的读端。

     5.父进程将要传输的数据写入管道的写端。

     6.子进程从管道的读端读取数据。

       父进程可以通过管道将数据传输给子进程,子进程可以通过管道接收父进程传输的数据。这样,父进程和子进程就可以进行进程间通信了。

       需要注意的是,管道的容量是有限的,如果管道被写满后继续写入数据,写入操作会被阻塞,直到有数据被读取出来为止。同样,如果管道为空时读取数据,读取操作也会被阻塞,直到有数据被写入为止。因此,在使用共享管道进行进程间通信时,需要合理控制数据的读写操作,以避免阻塞问题的发生。


三、深度理解管道

1.文件描述符角度

1.父进程创建管道

2.父进程fork出子进程

3.父进程关闭fd[0],子进程关闭fd[1]

2.内核角度-内核本质

       管道的实现机制:内核中的管道是通过一对文件描述符来实现的。一个文件描述符用于读取管道数据,另一个文件描述符用于写入管道数据。内核维护着一个缓冲区,用于存放从写入端写入的数据,并且从读取端读取的数据会从缓冲区中删除。

       管道的数据传输:管道是一种半双工的通信方式,数据只能单向流动。当写入端写入数据时,数据会被放入缓冲区中,直到被读取端读取。如果缓冲区已满,则写入操作会被阻塞,直到缓冲区有空闲空间。同样,如果缓冲区为空,则读取操作会被阻塞,直到缓冲区有数据。

       管道的进程同步:当多个进程使用管道通信时,可能会出现进程同步的问题。例如,如果写入端连续写入数据,而读取端没有及时读取,那么缓冲区可能会溢出。为了解决这个问题,内核提供了一些同步机制,例如管道的阻塞和非阻塞模式、管道的读取和写入端都关闭时的特殊情况等。

       管道的文件描述符操作:在内核中,文件描述符是一种操作系统提供给用户空间的接口。通过文件描述符的操作,可以实现对管道的读取和写入。对于读取操作,可以使用read系统调用从管道中读取数据;对于写入操作,可以使用write系统调用向管道中写入数据。


结语:关于理解Linux系统下的进程间通信与管道基础的分享到这里就结束了,没有进行展示的操作大家可以自行练习,希望本篇文章的分享会对大家的学习带来些许帮助,如果大家有什么问题,欢迎大家在评论区留言~~~ 

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

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

相关文章

idea开发 java web 酒店推荐系统bootstrap框架开发协同过滤算法web结构java编程计算机网页

一、源码特点 java 酒店推荐推荐系统是一套完善的完整信息系统&#xff0c;结合java web开发和bootstrap UI框架完成本系统 采用协同过滤算法进行推荐 &#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式…

Excel列匹配VLookUp功能使用

生活中很多关于excel多列数据进行匹配计算等场景,其中最常用的一个函数就是VLookUp了,下面直接上图: 得到结果如下: 得到结果如下: 注意: 1.在需要把计算完的数据粘贴到另一列或者另个sheet时,复制后,不要直接ctrlv粘贴,这样会把计算公式粘贴到对应的列.正确做法是:右键粘贴,选…

redis 的StringRedisTemplate

6.3 StringRedisTemplate 尽管JSON的序列化方式可以满足我们的需求&#xff0c;但依然存在一些问题&#xff0c;如图&#xff1a; 为了在反序列化时知道对象的类型&#xff0c;JSON序列化器会将类的class类型写入json结果中&#xff0c;存入Redis&#xff0c;会带来额外的内存…

Redis中的复制功能(三)

复制 服务器运行ID 除了复制偏移量和复制积压缓冲区之外&#xff0c;实现部分重同步还需要用到服务器运行ID(run ID): 1.每隔Redis服务器&#xff0c;不论主服务器还是从服务&#xff0c;都会有自己的运行ID2.运行ID在服务器启动时自动生成&#xff0c;由40个随机的十六进制…

基于kmeans的聚类微博舆情分析系统

第一章绪论 1.1研究背景 如今在我们的生活与生产的每个角落都可以见到数据与信息的身影。自从上十世纪八十年代的中后期开始&#xff0c;我们使用的互联网技术已经开始快速发展&#xff0c;近些年来云计算、大数据和物联网等与互联网有相领域的发展让互联网技术达到了史无前例…

浅谈iOS开发中的自动引用计数ARC

1.ARC是什么 我们知道&#xff0c;在C语言中&#xff0c;创建对象时必须手动分配和释放适量的内存。然而&#xff0c;在 Swift 中&#xff0c;当不再需要类实例时&#xff0c;ARC 会自动释放这些实例的内存。 Swift 使用 ARC 来跟踪和管理应用程序的内存&#xff0c;其主要是由…

Vue-Next-Admin:适配手机、平板、PC的开源后台管理模板

摘要&#xff1a;随着移动设备和PC的普及&#xff0c;为了满足不同设备的需求&#xff0c;开发一个能够自适应手机、平板和PC的后台管理系统变得至关重要。本文将介绍一个基于Vue3.x、Typescript、Vite、Element Plus等技术的开源模板库——Vue-Next-Admin&#xff0c;帮助开发…

rust项目组织结构和集成测试举例

概述 在学习rust的过程中&#xff0c;当项目结构略微复杂的时候&#xff0c;写集成测试的时候发现总是不能引用项目中的代码&#xff0c;导致编写测试用例失败。查阅了教程&#xff0c;一般举例都很简单。查阅了谷歌和百度以及ai&#xff0c;也没有找到满意的答案。这里记录一…

Spark-Scala语言实战(10)

在之前的文章中&#xff0c;我们学习了如何在spark中使用RDD的filter,distinct,intersection三种方法。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢。 Spark-…

Android 窗口那些事儿

目录 1. &#x1f4c2; 前言 你&#xff0c;是否有过这些疑问&#xff1f; 2. &#x1f531; Window 2.1 认识 Window 的几个阶段 1&#xff09;阶段一&#xff1a;Window 约等于 Activity 2&#xff09;阶段二&#xff1a;Window 约等于 View 3&#xff09;阶段三&…

【六 (2)机器学习-机器学习建模步骤/kaggle房价回归实战】

一、确定问题和目标&#xff1a; 1、业务需求分析&#xff1a; 与业务团队或相关利益方进行深入沟通&#xff0c;了解他们的需求和期望。 分析业务流程&#xff0c;找出可能的瓶颈、机会或挑战。 思考机器学习如何帮助解决这些问题或实现业务目标。 2、问题定义&#xff1a;…

Android Studio的Profiler生成trace排查Android冷启动耗时,Kotlin

Android Studio的Profiler生成trace排查Android冷启动耗时&#xff0c;Kotlin 利用AS自带的Profiler抓取trace排查定位冷启动耗时方法&#xff0c;不用写代码&#xff0c;直接配置AS即可完成。 例如下面代码&#xff1a; import android.os.Bundle import androidx.appcompat…

计算机网络-HTTP相关知识-RSA和ECDHE及优化

HTTPS建立基本流程 客户端向服务器索要并验证服务器的公钥。通过密钥交换算法&#xff08;如RSA或ECDHE&#xff09;协商会话秘钥&#xff0c;这个过程被称为“握手”。双方采用会话秘钥进行加密通信。 RSA流程 RSA流程包括四次握手&#xff1a; 第一次握手&#xff1a;客户…

vue3项目运行正常但vscode红色波浪线报错

以下解决办法如不生效&#xff0c;可尝试 重启 vscode 一、Vetur插件检测问题 vetur 是一个 vscode 插件&#xff0c;用于为 .vue 单文件组件提供代码高亮以及语法支持。但 vue 以及 vetur 对于 ts 的支持&#xff0c;并不友好。 1、原因 如下图&#xff1a;鼠标放到红色波浪…

基于单片机和ICL7135多档位数字电压表设计

**单片机设计介绍&#xff0c;基于单片机和ICL7135多档位数字电压表设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机和ICL7135的多档位数字电压表设计是一个结合了硬件与软件技术的综合性项目。这种设计旨在实现一…

VLAN间路由

部署了VLAN的传统交换机不能实现不同VLAN间的二层报文转发&#xff0c;因此必须引入路由技术来实现不同VLAN间的通信。VLAN路由可以通过二层交换机配合路由器来实现&#xff0c;也可以通过三层交换机来实现&#xff1b; VLAN间通讯限制 每个VLAN都是一个独立的广播域&#xff…

DolphinScheduler on k8s 云原生部署实践

文章目录 前言利用Kubernetes技术云原生平台初始化迁移基于Argo CD添加GitOpsDolphinScheduler 在 k8s 上的服务自愈可观测性集成服务网格云原生工作流调度从HDFS升级到S3文件技术总结 前言 DolphinScheduler 的高效云原生部署模式&#xff0c;比原始部署模式节省了95%以上的人…

SpringBoot整合Activiti7——实战之出差流程(分支)

文章目录 代码实现部署流程启动流程查询任务填写出差审批单经理审批xml文件 出差流程&#xff1a;开始 - 填写出差表单 - 判断&#xff08;出差天数大于等于5&#xff09;- 副经理审批 - 否则总经理审批 - 完成 代码实现 部署流程 Testpublic void testDeployProcess() throws …

Vue2(完结):replace属性、编程式路由导航、缓存路由组件、两个新钩子、路由守卫、history与hash

一、router-link的replace属性 1、作用&#xff1a;控制路由跳转时操作浏览器历史记录的模式 2、浏览器的历史记录有两种写入方式&#xff1a;分别为push和replace&#xff0c;push是追加历史记录&#xff0c;replace是替换当前记录。路由跳转时候默认为push 3、如何开启repla…

golang语言系列:Web框架+路由 之 Echo

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是golang语言系列文章&#xff0c;本篇主要对 Echo 框架 的基本使用方法 进行学习 1.Echo是什么 Go 有众多Web框架&#xff0c;Echo 是其中的一个&#xff0c;官网介绍Echo有高性能、可扩展性、极简的特点。使用E…