Linux中进程之间的通信

news2024/11/18 11:18:40

IPC的概念

即进程间的通信

常用方式:

1,管道通信:有名管道,无名管道

2,信号- 系统开销小

3,消息队列-内核的链表

4,信号量-计数器

5,共享内存

6,内存映射

7,套接字

无名管道

管道的概念

本质:

        内核缓冲区

        伪文件--不占用磁盘空间

特点:

        分为两部分:

                        读端,写端,对应两个文件描述符

                        数据写端流入,读端流出

        操作管理的进程被销毁之后,管道自动被释放

适用于有血缘关系的进程(父子进程)

管道默认是阻塞的:

阻塞模式确保了在数据写入管道之前,读取端不会继续执行,从而避免了读取到不完整或错误的数据。这种同步机制保证了数据的完整性和准确性。

阻塞模式下的代码通常更加直观和易于理解,因为它遵循了“等待-处理”的简单模式。

在阻塞模式,如果管道中没有数据可读,进程会挂起,等待数据到来,从而节省CPU资源。

阻塞模式可以防止在数据未完全写入管道之前就被读取,从而避免了潜在的数据泄露风险。

管道的管理

内部实现方式:队列(先进先出),而且是环形队列,确保数据的顺序性和高效性。

缓冲区大小:默认4k,大小会根据实际情况做出适当调整

管道局限性:队列使数据只能读取一次,不能重复读取,而且管道使半双工工作模式,只能进行单项通信。

匿名管道的创建

函数原型

#include <unistd.h> //包含的头文件

int pipe(int pipefd[2]);

参数:

创造管道的函数:pipe()

pipefd()是一个整型数组,用来存放管道的两个文件描述符,pipefd(0)是读端,pipefd(1)是写端。

返回值:如果创建成功,pipe()返回0;如果失败,返回-1,并用exit退出。

这里打印的文件描述符是3和4,是因为在通常的UNIX和类UNIX系统(如Linux)中,标准文件描述符(file descriptors)012 分别被预留给标准输入(stdin)、标准输出(stdout)标准错误输出(stderr)。当你调用 pipe() 函数时,它会在系统中分配两个新的文件描述符用于管道的读端和写端,这两个是连续的,当前可用的最小文件描述符。如果系统中已经有其他文件描述符被打开(例如,通过打开文件、套接字等),那么 pipe() 返回的文件描述符可能会更高(那就可能文件描述不是3和4了)。

父子进程间使用管道通信

这里我们通过父子进程管道通信实现ps aux | grep "bash"这个功能

在父进程中,我们需要先关闭读端,在子进程关闭写端,这样就实现了数据在父进程到子进程的方向上流动。

在进程中,我们调用了dup2函数:

起到数据重定向功能通过将特定文件描述符复制到标准输入、输出或错误输出的文件描述符,可以实现I/O重定向。例如,将一个文件描述符复制到标准输出,可以使程序的输出结果保存到文件中而非显示在屏幕上

函数原型为:int dup2(int oldfd, int newfd)。

这里,oldfd表示要被复制的文件描述符,而newfd则表示目标文件描述符的新编号。

当dup2成功执行时,它会返回新的文件描述符编号,即newfd的值;如果出错,则返回-1。

值得注意的是,在调用dup2之前,若newfd已经打开,系统会先关闭newfd指向的文件,以确保不会出现悬挂指针的情况。

使用execlp让父子进程执行两个程序

成功实现功能,对于两个grep bash进程的编号不同,是因为在我们使用终端执行命令时所产生的进程,所以会略有不同(进程编号一般比较接近)

管道的读写功能

1. 写入管道
  • 写入函数ssize_t write(int fd, const void *buf, size_t count);
    • fd:管道写端的文件描述符(pipefd[1])。
    • buf:指向要写入数据的缓冲区的指针。
    • count:要写入的数据的字节数。
  • 写入行为
    • 如果管道未满,write函数将数据写入管道,并返回实际写入的字节数。
    • 如果管道已满且写端未被关闭,write函数将阻塞,直到有空间可用或管道被关闭。
    • 如果管道读端全部被关闭,且写端尝试写入数据,将导致进程异常终止(除非捕获SIGPIPE信号)。
2. 读取管道
  • 读取函数ssize_t read(int fd, void *buf, size_t count);
    • fd:管道读端的文件描述符(pipefd[0])。
    • buf:指向用于存储读取数据的缓冲区的指针。
    • count:请求读取的字节数。
  • 读取行为
    • 如果管道中有数据,read函数从管道中读取指定数量的数据(或管道中剩余的所有数据,如果剩余数据少于请求的数量),并返回实际读取的字节数。
    • 如果管道中没有数据且写端未被关闭,read函数将阻塞,直到有数据可读或管道被关闭。
    • 如果管道写端全部被关闭,且读端尝试读取数据,read函数将返回0,表示文件结束(EOF)。

学到消息队列时候会详细讲

这边简单的举个例子

#include <stdio.h>  
#include <stdlib.h>  
#include <unistd.h>  
#include <string.h>  
#include <sys/wait.h>  
  
int main() {  
    int pipefd[2]; // 定义一个整型数组来存储管道的两个文件描述符  
    pid_t pid; // 定义一个变量来存储子进程的PID  
    char buf[100]; // 定义一个缓冲区来存储从管道中读取的数据  
  
    // 创建管道  
    if (pipe(pipefd) == -1) {  
        perror("pipe");  
        exit(EXIT_FAILURE);  
    }  
  
    // 创建子进程  
    pid = fork();  
  
    if (pid == -1) {  
        perror("fork");  
        exit(EXIT_FAILURE);  
    }  
  
    // 子进程代码  
    if (pid == 0) {  
        close(pipefd[1]); // 关闭子进程中的写端,因为我们只从管道读取数据  
  
        // 从管道中读取数据  
        ssize_t bytes_read = read(pipefd[0], buf, sizeof(buf) - 1);  
        if (bytes_read > 0) {  
            buf[bytes_read] = '\0'; // 确保字符串以null结尾  
            printf("Received from parent: %s\n", buf);  
        }  
  
        close(pipefd[0]); // 关闭读端  
        exit(EXIT_SUCCESS); // 子进程结束  
    }  
  
    // 父进程代码  
    close(pipefd[0]); // 关闭父进程中的读端,因为我们只向管道写入数据  
  
    // 向管道写入数据  
    const char *msg = "Hello from parent";  
    write(pipefd[1], msg, strlen(msg) + 1); // 包括字符串的null终止符  
  
    close(pipefd[1]); // 关闭写端  
  
    // 等待子进程结束  
    wait(NULL);  
  
    return 0;  
}

管道缓冲区大小

查看缓冲区大小命令:ulimit -a

可以看出pipe size(管道缓冲区大小时512bytes*8=4096bytes=4kb)

通过函数fpathcon也可查看,fpathcon是一个用于查询与文件描述符相关联的运行时配置信息的函数

函数原型:

#include <unistd.h>

long fpathconf(int fd, int name);

返回值时长整型,正确返回时,返回查询到的配置值,查询失败,返回-1,并设置error指示错误原因

有名管道

函数原型

头文件:#include<sys/types.h>     #include <sys/stat.h>

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

功能:创建管道文件

参数:管道文件文件名,权限,创建的文件权限仍然和umask有关系。

返回值:创建成功返回0,创建失败返回-1。

1.特点

有名管道 在磁盘上有这样一个文件 ls -l ->p

也是一个伪文件,在磁盘大小永久为0

数据存在内核中有一个对应的缓冲区

半双工通信方式

2.使用场景

没有血缘关系的进程间通信

3.创建方式

命令:mkfifo 管道名

函数:mkfifo

4.fifo文件可以使用io函数进程操作

   open/close

   read/write

   不能执行lseek操作

创建有名管道,即创建了一个节点,让这个节点指向我们的内核缓冲区

创建成功

我们可以在设置的路径中找到所创建的管道文件,并且文件权限第一个为p,表示这个文件是一个管道文件

有名管道的进程间通信

使用open函数读取管道文件中的数据

使用write写入数据到管道文件中

当我们分两个终端执行的时候,我们先执行read命令,但是管道文件里面没有,会等待管道里面写入东西,我们在另外一个终端执行write命令时,会把数据写入到管道文件中,同时read命令也会读取到这个数据并显示

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

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

相关文章

轻松合并PDF文档:2024年精选工具指南

不知道你有没有做PDF文件的经历&#xff0c;特别是多部门协同的那种。这时候如果有个可以支持pdf合并的工具那简直不要太开心了。独乐乐不如众乐乐&#xff0c;我把我用过的一些PDF合并工具这里介绍一下吧。 1.PDF编辑器福晰在线 直达链接&#xff1a;https://edit.foxitclou…

Java并发编程(下)

volatile的应用 - volatile修饰类属性&#xff08;类变量和实例变量&#xff09;&#xff0c;synchronized修饰类方法、代码块&#xff0c;同时volatile在并发中是**不安全**的 - 作用&#xff1a; - 使共享变量在多线程间可见&#xff0c;如果一个字段被声明成volatile&…

【Linux网络】应用层协议:HTTP 与 HTTPS

本篇博客整理了 TCP/IP 分层模型中应用层的 HTTP 协议和 HTTPS协议&#xff0c;旨在让读者更加深入理解网络协议栈的设计和网络编程。 目录 一、协议是什么 1&#xff09;结构化数据的传输 2&#xff09;序列化和反序列化 补&#xff09;网络版计算器 .1- 协议定制 .2- …

在window将Redis注册为服务

将redis注册为系统服务&#xff0c;开启自启动 安装服务 默认注册完之后会自动启动&#xff0c;在window中的服务看一下&#xff0c;如果启动类型为自动&#xff0c;状态是自动运行则启动完成。如果是手动&#xff0c;需要右键属性调整为自动&#xff0c;在点击启动&#xff0c…

LangChain4j-RAG高级-检索增强器

Retrieval Augmentor 检索增强器 RetrievalAugmentor 是 RAG 管道的入口点。它负责使用从各种来源检索的相关 Content 来扩充 ChatMessage 。 可以在创建 AiService 期间指定 RetrievalAugmentor 的实例&#xff1a; Assistant assistant AiServices.builder(Assistant.cla…

Mysql-覆盖索引和前缀索引

一.SQL提示 SQL提示,是优化数据库的一个重要手段,简单来说&#xff0c;就是在SQL语句加入一些人为的提示来达到 二.覆盖索引 尽量使用覆盖索引(查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到),减少select* 知识小贴士: using index condition :查找…

chk是什么文件格式 chk文件怎么恢复正常 chkdsk文件损坏怎么修复

在使用电脑和移动存储设备时&#xff0c;有时我们会发现磁盘中出现了大量的chk文件。这些chk文件无法打开&#xff0c;也无法得知其原本内容。那么&#xff0c;这些chk文件是什么呢&#xff1f;又该如何将chk文件恢复正常呢&#xff1f; chk文件是什么&#xff1f; 在我们查看…

环境搭建-Docker搭建ClickHouse

Docker搭建ClickHouse 一、前言二、ClickHouse安装2.1 拉取镜像运行ClickHouse服务 三、测试安装3.1 进入clickhouse容器3.2 命令补充说明 四、测试连接五、设置CK的用户名密码 一、前言 本文使用的Docker使用Windows搭建&#xff0c;Linux版本的搭建方式一样。 Windows系统搭…

【HarmonyOS】HarmonyOS NEXT学习日记:七、页面与组件的生命周期

【HarmonyOS】HarmonyOS NEXT学习日记&#xff1a;七、页面与组件的生命周期 页面和组件 组件&#xff1a;用Component装饰的代码称为自定义组件页面&#xff1a;Entry装饰的组件即页面的根节点 组件生命周期 aboutToAppear&#xff1a;在创建自定义组件的新实例后&#xf…

GPS定位系统(VUE框架)

源码下载&#xff1a;小宅博客网 博主之前写的《GPS定位系统&#xff08;MVC框架&#xff09;》版本&#xff0c;并没有做到前后端分离&#xff0c;不太适合多人协作开发&#xff0c;这边博主分享一个基于asp.net web api vue3的GPS定位系统框架&#xff0c;本框架继承了MVC框…

【Hot100】LeetCode—416. 分割等和子集

目录 题目1- 思路2- 实现⭐152. 乘积最大子数组——题解思路 3- ACM 实现 题目 原题连接&#xff1a;416. 分割等和子集 1- 思路 理解为背包问题 思路&#xff1a; 能否将均分的子集理解为一个背包&#xff0c;比如对于 [1,5,11,5]&#xff0c;判断能否凑齐背包为 11 的容量…

【shell】shell循环的几种方式

Shell循环的方式 for循环 for 变量名 in 值列表 do命令1命令2... done值列表情形&#xff1a; 值铺开变量数组 值铺开 变量 数组 while循环 while 条件判断 do命令1命令2... done条件判断情形 计算比较读取文本 计算比较 读取文本 until循环 until 条件 do命令1命令2... …

Imagination 面向大学推出 RISC-V 课程

Imagination Technologies发布了针对本科教学的 RISC-V 计算机架构完整课程&#xff0c;帮助学生了解处理器架构的关键元素&#xff0c;包括知识产权 (IP) 内核、修改 RISC-V 内核及其微架构。 该课程名为“RVfpga&#xff1a;理解计算机架构”&#xff0c;包含教学材料和实践…

【C++指南】类和对象(下)

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《数据结构与算法》 期待您的关注

论文阅读_字节的语音生成模型_Seed-TTS

英文名称: Seed-TTS: A Family of High-Quality Versatile Speech Generation Models 中文名称: Seed-TTS&#xff1a;高质量多功能语音生成模型系列 链接: http://arxiv.org/abs/2406.02430v1 代码: https://github.com/BytedanceSpeech/seed-tts-eval (评测工具) 演示网站&am…

shell-awk命令详解

目录 一.概述 二.工作原理 三.工作流程 1.运行模式 2.运行流程 四.基本语法 1.命令格式 2.常用变量  五.变量类型 1.内建变量 2.内置变量 3.BEGIN END运算  4.awk高级用法 5.awk if语句 6.BEGIN END循环 一.概述 AWK是一种处理文本文件的语言&#xff0c;是一…

深入分析 Android ContentProvider (六)

文章目录 深入分析 Android ContentProvider (六)ContentProvider 的性能优化和实践案例&#xff08;续&#xff09;1. 性能优化技巧&#xff08;续&#xff09;1.6. 使用批量插入优化性能示例&#xff1a;批量插入实现 1.7. 使用 Projections 优化查询示例&#xff1a;使用 Pr…

Webpack 从入门到精通

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 一、Webpack 简介 二、Webpack 的核心概念 三、Webpack 的安装与配置 安装 Node.js 安装 Webpack 初始…

【Linux C | 网络编程】进程池退出的实现详解(五)

上一篇中讲解了在进程池文件传输的过程如何实现零拷贝&#xff0c;具体的方法包括使用mmap&#xff0c;sendfile&#xff0c;splice等等。 【Linux C | 网络编程】进程池零拷贝传输的实现详解&#xff08;四&#xff09; 这篇内容主要讲解进程池如何退出。 1.进程池的简单退…

超越基础功能:项目进度管理工具深度评测

国内外主流的10款项目进度管理网站对比&#xff1a;PingCode、Worktile、滴答清单&#xff08;TickTick&#xff09;、Todoist、NarTick、Teambition、Monday.com、Asana、ClickUp、Trello。 在选择合适的项目进度管理工具时&#xff0c;许多项目经理面临着如何找到既能满足团队…