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

Linux 进程间通讯

Linux IPC 方式

在Linux系统中,进程间通信(IPC)是多个运行中的程序或进程之间交换数据和信息的关键机制。Linux提供了多种IPC机制,每种机制都有其特定的用途和优势。以下是Linux上主要的IPC通信方式:

  1. 管道(Pipes)

    • 管道是Linux中最古老的IPC机制之一,它允许数据从一个进程(生产者)流向另一个进程(消费者)。管道是半双工的,即数据只能在一个方向上传输。
    • 无名管道:仅在具有亲缘关系的进程(如父进程和子进程)之间可用,一旦创建了管道,它就与创建它的进程相关联。
    • 命名管道(FIFO):可以在没有亲缘关系的进程之间使用,它们是文件系统中的特殊文件,可以跨启动会话使用。
  2. 消息队列(Message Queues)

    • 消息队列允许进程之间传递结构化的消息,每个消息都有一个类型,这使得消息的过滤成为可能。
    • 消息队列是系统V IPC的一部分,可以在多个进程中使用,即使进程重启后仍然存在。
  3. 信号量(Semaphores)

    • 信号量用于控制对共享资源的访问,避免竞态条件。它们可以是二进制(只有0和1的状态)或计数信号量(可以有多个单位)。
    • 信号量同样属于系统V IPC的一部分,可以跨进程使用,用于同步进程间的操作。
  4. 共享内存(Shared Memory)

    • 共享内存允许多个进程直接访问同一块内存区域,这是最快的IPC机制,因为数据不需要复制。
    • 使用共享内存时,通常还需要信号量或互斥锁来防止多个进程同时修改同一数据。
  5. 信号(Signals)

    • 信号是软件中断,可以由硬件事件、软件异常或另一个进程发送给进程。它们主要用于通知进程发生了某些事件。
    • 信号本身并不携带大量数据,但是可以触发进程执行特定的操作。
  6. 套接字(Sockets)

    • 套接字提供了进程间通信的网络接口,不仅限于本地进程间通信,还可以用于网络通信。
    • 包括流式套接字(SOCK_STREAM,类似TCP)和数据报套接字(SOCK_DGRAM,类似UDP)。
  7. 流(Streams)

    • 流类似于管道,但它们提供了更复杂的通信机制,支持错误处理、流控制和多路复用。
  8. 内存映射文件(Memory-Mapped Files)

    • 虽然严格来说这不是传统的IPC机制,但通过将文件映射到内存中,进程可以像访问内存一样访问文件,从而实现进程间的数据共享。

选择IPC机制时,应考虑通信的需求(如速度、可靠性、复杂性、数据大小等),以及进程之间的关系(如是否在同一台机器上,是否有亲缘关系等)。例如,对于需要高速数据传输的场景,共享内存可能是最佳选择,而如果需要在网络上的多个机器之间通信,则应使用套接字。

几种常用的方式举例说明

1. 管道(Pipes)

  • 匿名管道(Anonymous Pipes):只能用于有亲缘关系的进程之间(如父子进程)。通过pipe()系统调用创建,数据以字节流的形式在进程之间传输。
    • 示例:
      int fd[2];
      pipe(fd);
      if (fork() == 0) {// 子进程close(fd[1]);char buf[100];read(fd[0], buf, sizeof(buf));printf("Child read: %s\n", buf);close(fd[0]);
      } else {// 父进程close(fd[0]);write(fd[1], "Hello from parent", 17);close(fd[1]);
      }
  • 命名管道(Named Pipes/FIFOs):可以用于没有亲缘关系的进程之间。通过mkfifo()系统调用创建。
    • 示例:
      mkfifo("/tmp/myfifo", 0666);
      if (fork() == 0) {// 子进程int fd = open("/tmp/myfifo", O_RDONLY);char buf[100];read(fd, buf, sizeof(buf));printf("Child read: %s\n", buf);close(fd);
      } else {// 父进程int fd = open("/tmp/myfifo", O_WRONLY);write(fd, "Hello from parent", 17);close(fd);wait(NULL); // 等待子进程结束unlink("/tmp/myfifo"); // 删除FIFO文件
      }

2. 消息队列(Message Queues)

  • 提供了一种基于消息的通信方式,允许发送和接收带类型的消息。通过msgget()msgsnd()msgrcv()系统调用进行操作。
    • 示例:
      key_t key = ftok("somefile", 65);
      int msgid = msgget(key, 0666 | IPC_CREAT);
      struct msg_buffer {long msg_type;char msg_text[100];
      } message;if (fork() == 0) {// 子进程message.msg_type = 1;msgrcv(msgid, &message, sizeof(message.msg_text), 1, 0);printf("Child received: %s\n", message.msg_text);
      } else {// 父进程message.msg_type = 1;strcpy(message.msg_text, "Hello from parent");msgsnd(msgid, &message, sizeof(message.msg_text), 0);wait(NULL); // 等待子进程结束msgctl(msgid, IPC_RMID, NULL); // 删除消息队列
      }

3. 共享内存(Shared Memory)

  • 允许多个进程直接访问同一块内存区域,通过shmget()shmat()shmdt()系统调用进行操作,通常需要配合信号量或互斥锁来控制访问。
    • 示例:
      key_t key = ftok("somefile", 65);
      int shmid = shmget(key, 1024, 0666 | IPC_CREAT);
      char *str = (char*) shmat(shmid, NULL, 0);if (fork() == 0) {// 子进程sleep(1); // 确保父进程先写入printf("Child read: %s\n", str);shmdt(str);
      } else {// 父进程strcpy(str, "Hello from parent");wait(NULL); // 等待子进程结束shmdt(str);shmctl(shmid, IPC_RMID, NULL); // 删除共享内存
      }

4. 信号量(Semaphores)

  • 用于控制对共享资源的访问,通过semget()semop()semctl()系统调用进行操作。
    • 示例:
      key_t key = ftok("somefile", 65);
      int semid = semget(key, 1, 0666 | IPC_CREAT);
      semctl(semid, 0, SETVAL, 1); // 初始化信号量为1
      struct sembuf sb = {0, -1, 0}; // P操作if (fork() == 0) {// 子进程semop(semid, &sb, 1); // P操作printf("Child in critical section\n");sleep(2);sb.sem_op = 1; // V操作semop(semid, &sb, 1);
      } else {// 父进程semop(semid, &sb, 1); // P操作printf("Parent in critical section\n");sleep(2);sb.sem_op = 1; // V操作semop(semid, &sb, 1);wait(NULL); // 等待子进程结束semctl(semid, 0, IPC_RMID); // 删除信号量
      }

5. 套接字(Sockets)

  • 适用于网络通信,也可以用于同一台机器上的进程间通信,支持面向连接的TCP和无连接的UDP协议。
    • 示例(Unix域套接字):
      int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
      struct sockaddr_un addr = {0};
      addr.sun_family = AF_UNIX;
      strcpy(addr.sun_path, "/tmp/mysocket");if (fork() == 0) {// 子进程sockfd = socket(AF_UNIX, SOCK_STREAM, 0);connect(sockfd, (struct sockaddr*)&addr, sizeof(addr));char buf[100];read(sockfd, buf, sizeof(buf));printf("Child read: %s\n", buf);close(sockfd);
      } else {// 父进程bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));listen(sockfd, 5);int connfd = accept(sockfd, NULL, NULL);write(connfd, "Hello from parent", 17);close(connfd);close(sockfd);wait(NULL); // 等待子进程结束unlink("/tmp/mysocket"); // 删除套接字文件
      }

这些IPC机制在实际开发中各有其适用场景,选择适合的方式可以有效地实现进程间的通信和数据共享。

相关文章:

Linux 进程间通讯

Linux IPC 方式 在Linux系统中,进程间通信(IPC)是多个运行中的程序或进程之间交换数据和信息的关键机制。Linux提供了多种IPC机制,每种机制都有其特定的用途和优势。以下是Linux上主要的IPC通信方式: 管道&#xff08…...

数据分析三剑客-Matplotlib

数据分析三剑客 数据分析三剑客通常指的是在Python数据分析领域中,三个非常重要的工具和库:Pandas、NumPy和Matplotlib。Pandas主要负责数据处理和分析,NumPy专注于数值计算和数学运算,而Matplotlib则负责数据可视化。这三个库相…...

FastAPI-Body、Field

参考:模式的额外信息 - 例子 - FastAPI 在FastAPI中,Body和Field是两个常用的注解,它们用于定义请求体中的数据或路径参数、查询参数等的处理方式。这两个注解都来自于Pydantic库,用于数据验证和解析,但它们的应用场景…...

软件设计师笔记-操作系统知识(二)

线程 以下是关于线程的一些关键点: 线程是进程中的一个实体:进程是操作系统分配资源(如内存空间、文件句柄等)的基本单位,而线程是进程中的一个执行单元。多个线程可以共享同一个进程的地址空间和其他资源。线程是CP…...

鸿蒙UI开发快速入门 —— part12: 渲染控制

如果你对鸿蒙开发感兴趣,加入Harmony自习室吧~👇🏻👇🏻👇🏻👇🏻 扫描下面的二维码关注公众号。 1、前言 在声明式描述语句中开发者除了使用系统组件外,还可…...

添加用户页面(Flask+前端+MySQL整合)

首先导入Flask库和pymysql库。Flask用于创建Web应用程序,pymysql用于连接和操作MySQL数据库。 from flask import Flask, render_template, request import pymysql创建一个Flask应用实例。__name__参数告诉Flask使用当前模块作为应用的名称。 app Flask(__name_…...

素数筛(算法篇)

算法之素数筛 素数筛 引言: 素数(质数):除了1和自己本身之外,没有任何因子的数叫做素数(质数) 朴素筛法(优化版) 概念: 朴素筛法:是直接暴力枚举2到当前判断的数x(不包括),然后看在这范围内是否存在因…...

迁移Microsoft Edge

如何将Microsoft Edge迁移到d盘?对于Microsoft Edge想必大部分人都不陌生,它是Windows操作系统的默认浏览器,存储用户的个人数据、缓存和设置等信息。有些时候,我们需要对Microsoft Edge中的数据进行数据迁移,以释放c盘…...

Maven高级理解属性

属性 在这一章节内容中,我们将学习两个内容,分别是 属性版本管理 属性中会继续解决分模块开发项目存在的问题,版本管理主要是认识下当前主流的版本定义方式。 4.1 属性 4.1.1 问题分析 讲解内容之前,我们还是先来分析问题: …...

Trilium Notes浏览器插件保存网页内容到docker私有化部署

利用Trilium浏览器插件可以很方便的把网页内容保存到Trilium,需要先在docker部署好trilium,还没有部署的可以先看这篇文章:trilium笔记私有化部署-www.88531.cn资享网 1.下载Trilium浏览器插件:https://www.npspro.cn/33462.html…...

C++ 统计二进制串中0出现的个数

描述 一个32位有符号整数,使用二进制来表示,现在要统计一下二进制串中0的个数。 示例1 输入: 11 返回值: 29 说明: 二进制00000000000000000000000000001011中有29位0 class Solution { public:/*** 代码中的…...

note-网络是怎样连接的6 请求到达服务器,响应返回浏览器

助记提要 服务器程序的结构套接字的指代方式MAC模块的接收过程IP模块的接收过程TCP模块处理连接包TCP模块处理数据包TCP模块的断开操作URI转换为实际文件路径URI调用程序Web服务器访问控制响应内容的类型 6章 请求到达服务器,响应返回浏览器 1 服务器概览 在数据…...

存储过程与函数:封装数据库逻辑的艺术(七)

引言 在上一章《事务处理》中,我们深入探讨了事务的ACID特性以及如何通过事务控制语句和隔离级别来确保数据的一致性和完整性。本章,我们将把焦点转向存储过程与函数,这是数据库系统中用于封装复杂业务逻辑和增强代码复用性的强大工具。通过…...

【复旦邱锡鹏教授《神经网络与深度学习公开课》笔记】卷积

卷积经常用在信号处理中,用于计算信号的延迟累积。假设一个信号发射器每个时刻 t t t产生一个信号 x t x_t xt​,其信息的衰减率为 w k w_k wk​,即在 k − 1 k-1 k−1个时间步长后,信息为原来的 w k w_k wk​倍,时刻 …...

Trie字符串统计

Trie字符串统计 维护一个字符串集合,支持两种操作: I x 向集合中插入一个字符串 x;Q x 询问一个字符串在集合中出现了多少次。 共有 N个操作,所有输入的字符串总长度不超过 105,字符串仅包含小写英文字母。 输入格式…...

Kali Linux源

中科大 deb http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib deb-src http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib阿里云 deb http://mirrors.aliyun.com/kali kali-rolling main non-free contrib deb-src http://mirrors.…...

【RT摩拳擦掌】基于RT106L/S语音识别的百度云控制系统

【RT摩拳擦掌】基于RT106L/S语音识别的百度云控制系统 一 文档简介二 平台构建2.1 使用平台2.2 百度智能云2.2.1 物联网核心套件2.2.2 在线语音合成 2.3 playback语音数据准备与烧录2.4 开机语音准备与添加2.5 唤醒词识别词命令准备与添加 三 代码准备3.1 sln-local/2-iot 代码…...

国标GB28181视频汇聚平台EasyCVR设备展示数量和显示条数不符的原因排查与解决

国标GB28181/GA/T1400协议/安防综合管理系统EasyCVR视频汇聚平台能在复杂的网络环境中,将前端设备统一集中接入与汇聚管理。智慧安防/视频存储/视频监控/视频汇聚EasyCVR平台可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级…...

FastAPI教程I

本文参考FastAPI教程https://fastapi.tiangolo.com/zh/tutorial 第一步 import uvicorn from fastapi import FastAPIapp FastAPI()app.get("/") async def root():return {"message": "Hello World"}if __name__ __main__:uvicorn.run(&quo…...

如何在 HTML 中实现响应式设计以适应不同设备的屏幕尺寸?

要在HTML中实现响应式设计以适应不同设备的屏幕尺寸,可以使用CSS媒体查询和流动布局。 以下是实现响应式设计的一些关键步骤: 使用CSS媒体查询:CSS媒体查询允许根据屏幕尺寸和设备特性应用不同的CSS样式。通过在CSS中使用media规则&#xf…...

Nature级研究启动前必做这5步:Perplexity智能检索校准清单(20年顶刊审稿人压箱底工作流)

更多请点击: https://intelliparadigm.com 第一章:Nature级研究启动前的智能检索认知革命 在高影响力科研项目(如 Nature、Science 级别)立项初期,传统关键词检索已无法应对跨学科文献爆炸、语义歧义与隐性知识关联等…...

MSP 盈利、留客、提口碑,核心就盯这12个 KPI

很多 MSP(托管服务提供商)都会陷入一个误区,手里握着一堆散落在各个看板的运营数据,却始终搞不清哪些指标能真正帮自己提升服务质量、拉高利润、留住客户。忙忙碌碌做了一堆报表,最终还是凭感觉做决策,业务…...

开源项目本地化实战:从Presentify翻译项目看国际化协作

1. 项目概述:一个被忽视的开源宝藏如果你是一个经常需要做演示、录屏或者线上教学的开发者、讲师或者知识分享者,那你一定遇到过这个痛点:如何在屏幕上清晰地标注你的鼠标点击、按键操作,让观众能毫不费力地跟上你的思路&#xff…...

Python自动化交易:Kalshi预测市场API封装与量化策略实践

1. 项目概述:一个为Kalshi预测市场打造的自动化工具箱如果你对预测市场感兴趣,或者正在寻找一种程序化的方式来管理你在Kalshi平台上的交易活动,那么你可能会对这个名为kalshi-skill的项目产生共鸣。简单来说,这是一个基于Python的…...

ARM动态内存控制器与SDRAM地址映射技术详解

1. ARM动态内存控制器基础解析动态内存控制器(Dynamic Memory Controller,简称DMC)是现代嵌入式系统中管理SDRAM等易失性存储器的核心组件。作为处理器与存储设备之间的桥梁,DMC通过高效的地址映射技术实现两者间的数据通信。在AR…...

OpenClaw引发AI Agent狂欢,深圳机密计算科技打造全链路安全基座

OpenClaw:AI Agent狂欢的导火索当AI Agent从实验室走向产业爆发,技术革命与安全危机正同步抵达临界点。2026年初,OpenClaw横空出世,彻底点燃了全球AI Agent的狂欢。它仅用60天,便打破React保持十年的GitHub Star纪录&a…...

服务器卡死别慌!手把手教你读懂NMI watchdog的soft lockup报错信息(附CentOS 7排查流程)

服务器卡死应急指南:NMI watchdog与soft lockup实战排查手册 凌晨三点,机房告警铃声大作,监控大屏上某台核心服务器的CPU使用率突然飙升至100%并持续不降。登录系统后,dmesg中赫然出现NMI watchdog: BUG: soft lockup - CPU#2 stu…...

Clawforce:开源AI智能体团队基础设施,实现持久化与安全协作

1. 项目概述:Clawforce,一个为持久化AI智能体团队构建的基础设施最近在AI智能体领域,一个词被反复提及:“Agentic AI”,即智能体驱动的AI。这不再是让单个AI模型回答一个问题那么简单,而是构建一个能够自主…...

在Taotoken模型广场中根据任务与预算选择合适的模型

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 在Taotoken模型广场中根据任务与预算选择合适的模型 当开发者需要将大模型能力集成到自己的应用或工作流中时,面对市场…...

Codex入门10-Goal自主任务(进阶必学:设定目标就不管了,AI自己干活到完成)

🎯 本文目标 掌握 /goal 持久化任务系统,让 Codex 自主完成复杂的大型工作。 🤔 /goal 和普通对话有什么区别? 对比 普通对话 /goal 任务 交互方式 一问一答 设定目标后AI自主工作 持久性 关终端就中断 关终端也能继续 适合任务 小任务、即时反馈 大任务、长期执行 计划…...