Linux进程间通讯 -- 管道

news2024/9/28 3:22:47

Linux进程间通讯 – 管道

文章目录

  • Linux进程间通讯 -- 管道
    • 1. 原理
    • 2. 进程间通讯
      • 2.1 管道
        • 2.1.1 匿名管道 `pipe`
        • 2.2.2 有名管道 `FIFO`
      • 2.2 信号
      • 2.3 共享内存
      • 2.4 本地套接字

1. 原理

Linux 进程间通讯,也称为IPC(InterProcess Communication)

在 Linux 中每个进程都具备独立的进程地址空间,对每个进程的独立地址空间进行划分,在0G - 3G部分被划分为用户空间,而3G - 4G部分被划分为内核地址空间。注意此0G - 4G 为虚拟地址空间,实际上会通过MMU映射到物理地址空间。

在进行地址映射的时候,每个进程的用户空间在实际物理空间上将被映射到多个地址空间,而多个进程的内核空间将会被被映射到同一块区域,因此多个进程之间具备相同的内核地址空间,通过此共同的内核地址空间实现线程间数据交互即为进程间通讯,也即IPC。
在这里插入图片描述

2. 进程间通讯

Linux进程间通讯的方式主要分为以下四大种类型:

  1. 管道 pipe
  2. 信号 signal
  3. 共享映射区 mmap
  4. 本地套接字 socket

2.1 管道

使用管道实现进程间通讯的优点是:使用简单!

管道分为有名管道 FIFO 和匿名管道 pipe,匿名管道仅能用于具备血缘关系的进程间通讯;而有名管道因其具备了名字可以被找到,因此可用于无血缘关系的进程间通讯。

管道本质是一个伪文件,是由内核管理的一个缓冲区,同时此缓冲区被设计成环形,具备两个端口,一端连接数据的写入,一端连接数据的输出,因此管道仅可用于单向通讯的场合

当管道中无有效数据时,从管道中读取数据时进入阻塞等待状态,直至有数据从管道的写端写入。

当管道中数据被写满时,再次往管道内写入数据会进入阻塞等待状态,直至有数据从管道的读端被读走。

2.1.1 匿名管道 pipe

创建管道:

#include <unistd.h>

int pipe(int pipefd[2]);
  • 传入参数:包含两个文件指针的数组,pipefd[0] 指向管道的读端;pipefd[1] 指向管道的写端
  • 返回值:0:成功 -1:失败

示例:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>

int main(int argc, char **argv)
{
    int fd[2] = { 0 };
    int ret = 0;
    pid_t pid = 0;
    char buf[512] = {0};

    ret = pipe(fd);
    if (ret < 0) {
        perror("create pipe failed");
        return -1;
    }

    pid = fork();
    if (pid == 0) {
        printf("----------Is child process ------------\n");
        close(fd[0]);       /* close the read of pipe. */
        write(fd[1], "hello world!\n", sizeof("hello world!\n"));
    } else {
        if (pid < 0) {
            perror("fork failed");
            return -1;
        }
        printf("----------Is father process -----------\n");
        close(fd[1]);       /* close the write of pipe. */

        while (1) {
            memset(buf, 0, sizeof(buf));
            ret = read(fd[0], buf, sizeof(buf));
            printf("ret:%d read:%s\n", ret, buf);
            sleep(1);
        }
    }

    return 0;
}

运行结果如下:
在这里插入图片描述
运行分析:

  1. 使用pipe创建一个匿名管道
  2. 使用fork创建子进程,父子进程均拥有此pipe
  3. 子进程关闭管道读端,延时1s后往管道写端写入数据
  4. 父进程关闭管道写端,之后马上对管道读端读取数据,此时由于管道内没有有效数据,因此父进程发生阻塞,直至子线程往管道内写入数据
  5. 子进程写完数据后进程结束,对应的写端口被系统关闭,因此父进程读取管道直接返回0,不再阻塞。
    在这里插入图片描述
2.2.2 有名管道 FIFO

创建有名管道:

#include <sys/types.h>
#include <sys/stat.h>

int mkfifo(const char *pathname, mode_t mode);
  • 传入参数:
    • pathname: 有名管道名字
    • mode: 有名管道对应文件的权限(8进制),最终文件权限为 (mode & ~umask),通常此值使用0664
  • 返回值:
    • 0: success -1:fail

注意事项:

  1. 如果存在有名管道对应名字的文件,则会返回错误 errno = EEXIST,因此没有做特殊处理时,重复运行此程序通常会报错。

  2. 创建好了有名管道之后,open此有名管道时,必须要求此管道的读端和写端均被打开,否则 open 函数会进入阻塞状态

    • 如果采用只读模式 open("test_fifo", O_RDONLY)打开,则open函数会阻塞直至其他函数采用O_WRONLYO_RDWR打开写端
    • 如果采用只写模式 open("test_fifo", O_WRONLY)打开,则open函数会阻塞直至其他函数采用O_RDONLYO_RDWR打开读端
    • 如果采用非阻塞方式打开只读端口 open("test_fifo", O_RDONLY | O_NONBLOCK) 不会报错,但采用非阻塞方式打开只写接口 open("test_fifo", O_WRONLY | O_NONBLOCK) 会返回 No such device or address 错误
    • 因此采用读写方式打开不会发送阻塞也不会报错 open("test_fifo", O_RDWR),但应用不一定安全!

示例:

fifo_r.c:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

int main(int argc, char **argv)
{
    int fd = 0, ret = 0;
    char buf[512] = {0};

    if (mkfifo("test_fifo", 0664) < 0 && errno != EEXIST) {
        perror("mkfifo error");
        return -1;
    }

    //fd = open("test_fifo", O_RDONLY | O_NONBLOCK);
    fd = open("test_fifo", O_RDONLY );
    if (fd < 0) {
        perror("open fifo error");
        return -1;
    }

    while (1) {
        ret = read(fd, buf, sizeof(buf));
        printf("read: ret:%d, buf = %s\n", ret, buf);
        sleep(1);
    }
    
    return 0;
}

fifo_w.c:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int main(int argc, char **argv)
{
    int fd = 0, ret = 0;
    int cnt = 0;
    char buf[512] = {0};

    if (mkfifo("test_fifo", 0664) < 0 && errno != EEXIST) {
        perror("mkfifo error");
        return -1;
    }

    //fd = open("test_fifo", O_RDWR);
    fd = open("test_fifo", O_WRONLY);
    if (fd < 0) {
        perror("open fifo error");
        return -1;
    }

    while (1) {
        cnt ++;
        snprintf(buf, sizeof(buf), "hello world! cnt:%d", cnt);

        ret = write(fd, buf, strlen(buf)+1);
        printf("write: ret:%d, buf = %s\n", ret, buf);
        sleep(2);
    }
    
    return 0;
}

运行结果:
在这里插入图片描述
对应创建的test_fifo文件如下
在这里插入图片描述

2.2 信号

//TODO:

2.3 共享内存

//TODO:

2.4 本地套接字

//TODO:

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

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

相关文章

C++实现网站内搜索功能

文章目录 搜索结果的结构下载我们需要的数据分析html结构数据处理去标签之标题去标签之正文内容构造url把上述的数据清理操作对每一个文件都做一遍把处理好的数据都保存到一个.bin文件 构建正排索引构建倒排索引使用cpp-jieba分词计算每个文档中的每个词的权重对所有文档都进行…

格密码基础:光滑参数

目录 一. 铺垫高斯函数 二. 光滑参数图形理解 三. 光滑参数与格基本区 3.1 高斯与均匀分布的统计距离 3.2 光滑参数理解 四. 光滑参数与最短向量 五. 光滑参数与连续最小值 六. 光滑参数与对偶格的上界 七. 光滑参数与格的上界 八. 小结 一. 铺垫高斯函数 定义高斯密…

Django 9 常用通用视图分析

View 提供基于不同http方法执行不同逻辑的功能。 1. 创建 terminal输入 django-admin startapp the_13回车 2.tutorial子文件夹 settings.py注册一下 INSTALLED_APPS [django.contrib.admin,django.contrib.auth,django.contrib.contenttypes,django.contrib.sessions,dja…

九州金榜|孩子步入叛逆期,常常离家出走怎么办?

孩子在拥有了独立意识后&#xff0c;就开始试图挑战父母的权威。他们会主动去质疑父母&#xff0c;主动去证明自己的成熟和独立&#xff0c;还会主动试图逃离父母的控制范围。 近日就收到了家长求助孩子离家出走问题的私信&#xff0c;在得到家长同意&#xff0c;接下来我们就…

Docker-Compose部署Redis(v7.2)分片集群(含主从)

文章目录 一、前提准备1. 文件夹结构 二、配置文件1. redis.conf2. docker-compose文件 三、构建集群1. 自动分配主从关系2.1 构建3 master集群2.2 手动配置从节点 四、测试1. 集群结构2. 分片测试 环境 docker desktop for windows 4.23.0redis 7.2 目标 搭建如下图分片主从…

利用ArcGIS探究环境与生态因子对水体、土壤、大气污染物等影响的实践技术

如何利用ArcGIS实现电子地图可视化表达&#xff1f;如何利用ArcGIS分析空间数据&#xff1f;如何利用ArcGIS提升SCI论文的层次&#xff1f;制图是地理数据展现的直观形式&#xff0c;也是地理数据应用的必要基础。本次课程从ArcGIS的基本操作、ArcGIS 的空间数据分析及ArcGIS 的…

算法基础之货仓选址

货仓选址 核心思想&#xff1a; 贪心 绝对值不等式 : ∣ x – a ∣ ∣ x – b ∣ ≥ ∣ a – b ∣ |x – a| |x – b| ≥ |a – b| ∣x–a∣∣x–b∣≥∣a–b∣ 将n个数两两分组 1~~ n-1 (奇数会剩一个) 分别用绝对值不等式 即可推出来 货仓位置应该在中位数上(奇数) 或在中…

鸿蒙应用开发 闹钟实现

后台代理提醒简介 随着生活节奏的加快&#xff0c;我们有时会忘记一些重要的事情或日子&#xff0c;所以提醒功能必不可少。应用可能需要在指定的时刻&#xff0c;向用户发送一些业务提醒通知。例如购物类应用&#xff0c;希望在指定时间点提醒用户有优惠活动。为满足此类业务…

C# Unity将地形(Terrain)导出成obj文件

C# Unity将地形(Terrain)导出成obj文件 从其他地方搬运过来的&#xff0c;只能到出obj模型&#xff0c;不能导出贴图 using System.IO; using System.Text; using UnityEditor; using UnityEngine; using System;enum SaveFormat { Triangles, Quads } enum SaveResolution {…

Landsat8的辐射定标与大气校正

目录 打开影像辐射定标大气校正计算区域高程计算研究区高程大气校正查看处理结果 打开影像 在文件夹中找到xxx_MTL.txt文件&#xff0c;拖到ENVI中 此处可能会出现无法打开的问题&#xff0c;参考该文章&#xff08;ENVI无法打开Landsat8的头文件问题和解决&#xff09; 辐…

Iceberg从入门到精通系列之十九:分区

Iceberg从入门到精通系列之十九&#xff1a;分区 一、认识分区二、Iceberg的分区三、Hive 中的分区四、Hive 分区问题五、Iceberg的隐藏分区六、分区变换七、分区变换 一、认识分区 分区是一种通过在写入时将相似的行分组在一起来加快查询速度的方法。 例如&#xff0c;从日志…

C#,冒泡排序算法(Bubble Sort)的源代码与数据可视化

排序算法是编程的基础。 常见的四种排序算法是&#xff1a;简单选择排序、冒泡排序、插入排序和快速排序。其中的快速排序的优势明显&#xff0c;一般使用递归方式实现&#xff0c;但遇到数据量大的情况则无法适用。实际工程中一般使用“非递归”方式实现。本文搜集发布四种算法…

【WPF】使用 WriteableBitmap 提升 Image 性能

【WPF】使用 WriteableBitmap 提升 Image 性能 前言WriteableBitmap 背景WriteableBitmap 渲染原理WriteableBitmap 使用技巧案例核心源码测试结果 前言 由于中所周不知的原因&#xff0c;WPF 中想要快速的更新图像的显示速率一直以来都是一大难题。在本文中&#xff0c;我将分…

leetcode“位运算”——只出现一次的数字

只出现一次的数字i&#xff1a; https://leetcode.cn/problems/single-number/ 给你一个非空整数数组 nums&#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次。找出那个只出现一次的元素。 class Solution { public:int singleNumber(vector<i…

九州金榜|孩子厌学,作为父母有想做自己的原因吗?

孩子不会天生就厌学&#xff0c;如果孩子天生厌学&#xff0c;那么孩子就不可能学会说话&#xff0c;走路&#xff0c;日常生活&#xff0c;更不可能去上学&#xff0c;孩子厌学因素非常多&#xff0c;而作为父母&#xff0c;你有没有想过是你的原因造成的呢&#xff1f;九州金…

【深度学习:Domain Adversarial Neural Networks (DANN) 】领域对抗神经网络简介

【深度学习&#xff1a;Domain Adversarial Neural Networks】领域对抗神经网络简介 前言领域对抗神经网络DANN 模型架构DANN 训练流程DANN示例 GPT示例 前言 领域适应&#xff08;DA&#xff09;指的是当不同数据集的输入分布发生变化&#xff08;这种变化通常被称为共变量变…

Redis概览

Redis存储是Key-Value结构的数据&#xff0c;其中Key是字符串类型&#xff0c;Value有5种常见的数据类型 字符串 String 哈希 hash 列表 list 集合 set 有序集合 sorted set / zset 各种数据类型的特性 字符串操作命令 : ● SET ke…

解决Vue3 中Echarts数据更新渲染不上问题

解决办法就是让Dom节点重新渲染 定义一个变量 const postLoading ref(true); 请求数据前dom节点不渲染&#xff0c;获取完数据重新渲染

2024年1月阿里云服务器租用价格表_优惠活动大全

2024年1月最新阿里云服务器租用价格表&#xff0c;云服务器ECS经济型e实例2核2G、3M固定带宽99元一年、轻量应用服务器2核2G3M带宽轻量服务器一年61元&#xff0c;2核4G4M带宽轻量服务器一年165元12个月、2核4G服务器30元3个月&#xff0c;云服务器ECS可以选择经济型e实例、通用…

静态网页设计——中医中药网(HTML+CSS+JavaScript)(dw、sublime Text、webstorm、HBuilder X)

前言 声明&#xff1a;该文章只是做技术分享&#xff0c;若侵权请联系我删除。&#xff01;&#xff01; 感谢大佬的视频&#xff1a;https://www.bilibili.com/video/BV11e411i7g8/?vd_source5f425e0074a7f92921f53ab87712357b 源码&#xff1a;https://space.bilibili.com…