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

Linux之IPC通信共享内存(一次拷贝)与消息队列、管道、信号量、socket(两次拷贝)总结(六十二)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

1.前言

本篇目的:理解IPC通信消息队列、管道、socket两次内存拷贝与共享内存一次内存拷贝。

2.IPC通信消息队列、管道、socket、共享内存介绍

  • 在Linux和Android中,进程间通信(IPC)的方式有很多种,包括管道(Pipe)、消息队列(Message Queue)、共享内存(Shared Memory)、信号量(Semaphore)、套接字(Socket)等。其中,管道、消息队列、套接字都需要进行两次内存拷贝,而共享内存只需要一次内存拷贝。

1. 两次内存拷贝的IPC方式:

  • 管道(Pipe): 当一个进程向管道中写入数据时,数据首先会被拷贝到内核缓冲区,然后当另一个进程从管道中读取数据时,数据会从内核缓冲区拷贝到该进程的内存空间。这就是两次内存拷贝。

  • 消息队列(Message Queue): 消息队列的工作方式与管道类似,数据在发送和接收时都需要经过内核缓冲区,因此也需要两次内存拷贝。

  • 套接字(Socket): 套接字在发送和接收数据时,数据也需要经过内核缓冥区,因此也需要两次内存拷贝。

2. 一次内存拷贝的IPC方式:

  • 共享内存(Shared Memory): 共享内存是最快的IPC方式,因为进程是直接对内存进行操作,数据不需要在进程和内核之间进行拷贝。但是,由于多个进程可以同时操作同一块内存,因此需要使用信号量等同步机制来防止数据的不一致。

3.总结

  • 一次内存拷贝:
    一次内存拷贝是指数据在用户空间和内核空间之间只进行了一次拷贝。在Linux和Android中,使用共享内存(shared memory)实现IPC通信是一种一次内存拷贝的方式。共享内存允许多个进程共享同一块物理内存,因此数据被写入内核空间后,其他进程可以直接在内存中读取数据,避免了多次拷贝的开销。

  • 两次内存拷贝:
    两次内存拷贝指数据在用户空间和内核空间之间进行了两次拷贝。在Linux和Android中,使用Socket、管道(pipe)和消息队列(message queue)进行IPC通信会涉及两次内存拷贝。

3.代码实例

1.共享内存进行一次内存拷贝

#include <iostream>
#include <sys/shm.h>
#include <cstring>int main() {key_t key = ftok("/tmp", 'S');int shmid = shmget(key, 1024, 0666 | IPC_CREAT);char *data = (char*)shmat(shmid, nullptr, 0);std::string message = "Hello, IPC using shared memory!";std::memcpy(data, message.c_str(), message.size());shmdt(data);shmctl(shmid, IPC_RMID, nullptr);return 0;
}

2.Socket进行两次内存拷贝

// 服务器端
#include <iostream>
#include <sys/socket.h>
#include <cstring>int main() {int server_sock = socket(AF_INET, SOCK_STREAM, 0);// 绑定和监听int client_sock = accept(server_sock, nullptr, nullptr);std::string message = "Hello, IPC using sockets!";send(client_sock, message.c_str(), message.size(), 0);close(client_sock);close(server_sock);return 0;
}// 客户端
#include <iostream>
#include <sys/socket.h>
#include <cstring>int main() {int client_sock = socket(AF_INET, SOCK_STREAM, 0);// 连接服务器char buffer[1024];recv(client_sock, buffer, sizeof(buffer), 0);std::cout << "Message received from server: " << buffer << std::endl;close(client_sock);return 0;
}

3.管道进行两次内存拷贝

#include <iostream>
#include <unistd.h>
#include <cstring>int main() {int pipe_fds[2];if (pipe(pipe_fds) == -1) {std::cerr << "Failed to create pipe" << std::endl;return 1;}const char* message = "Hello, IPC using pipes!";const size_t len = strlen(message);if (write(pipe_fds[1], message, len) != static_cast<ssize_t>(len)) {std::cerr << "Failed to write to pipe" << std::endl;return 1;}char buffer[64];ssize_t bytes_read = read(pipe_fds[0], buffer, sizeof(buffer));if (bytes_read == -1) {std::cerr << "Failed to read from pipe" << std::endl;return 1;}std::cout << "Message read from pipe: " << std::string(buffer, bytes_read) << std::endl;close(pipe_fds[0]);close(pipe_fds[1]);return 0;
}

4.消息队列进行两次内存拷贝

#include <iostream>
#include <cstring>
#include <sys/msg.h>struct Message {long type;char text[100];
};int main() {key_t key = ftok("/tmp", 'Q');int msgid = msgget(key, 0666 | IPC_CREAT);Message message;message.type = 1;std::strcpy(message.text, "Hello, IPC using message queues!");msgsnd(msgid, &message, sizeof(message.text), 0);msgrcv(msgid, &message, sizeof(message.text), 1, 0);std::cout << "Message received from message queue: " << message.text << std::endl;msgctl(msgid, IPC_RMID, nullptr);return 0;
}

5.信号量进行两次内存拷贝

#include <iostream>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <unistd.h>
#include <cstring>int main() {key_t key = ftok("/tmp", 'S');int semid = semget(key, 1, IPC_CREAT | 0666);if (semid == -1) {std::cerr << "Failed to create semaphore" << std::endl;return 1;}sembuf acquire = {0, -1, SEM_UNDO};sembuf release = {0, 1, SEM_UNDO};if (semop(semid, &acquire, 1) == -1) {std::cerr << "Failed to acquire semaphore" << std::endl;return 1;}// Critical section - perform operations that require exclusive accessstd::string message = "Hello, IPC using semaphores!";// Perform operations on the shared resourceif (semop(semid, &release, 1) == -1) {std::cerr << "Failed to release semaphore" << std::endl;return 1;}return 0;
}

相关文章:

Linux之IPC通信共享内存(一次拷贝)与消息队列、管道、信号量、socket(两次拷贝)总结(六十二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…...

【多线程 - 01、概述】

进程 几乎所有的操作系统都支持进程概念&#xff0c;进程是处于运行过程中的程序&#xff0c;进程是操作系统中进行资源分配的基本单位。 三个基本特征 独立性&#xff1a;指进程实体是一个能独立运行、独立获得资源和独立接受调度的基本单位。而对于未建立任何进程的程序&…...

SQL SELECT INTO 语句

SQL SELECT INTO 语句 使用 SQL&#xff0c;您可以将信息从一个表中复制到另一个表中。 SELECT INTO 语句从一个表中复制数据&#xff0c;然后将数据插入到另一个新表中。 SQL SELECT INTO 语法 我们可以把所有的列都复制到新表中&#xff1a; SELECT * INTO newtable [IN ex…...

【刷题】(AtCoder Beginner Contest 328) C、D 补题

前言 第一次打 a了两道 C、D都是TLE 看了其他人的题解之后 有一些想法 所以发一篇博客 C 题干 题目链接 我的思路及做题过程 我的思路是 输入left、right 再在这个区间内计算字母相同的对数 代码是&#xff1a; #include<iostream> #include<cmath> #includ…...

NI USRP软件无线设备的特点

NI USRP软件无线设备 NI的USRP(Universal Software Radio Peripheral)设备是RF应用中使用的软件无线(SDR)。NI的USRP收发器可以在多个频段发送和接收RF信号&#xff0c;因此可用于通信工程教育和研究。通过与LabVIEW开发环境相结合&#xff0c;USRP可以实现使用无线信号验证无…...

大数据毕业设计选题推荐-污水处理大数据平台-Hadoop-Spark-Hive

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…...

最新获取支付宝cardIndex参数图文教程

本章教程主要介绍如何获取支付宝的cardIndex参数。 目录 一、登录到支付宝官网 二、在历史记录中,找到对应用户 一、登录到支付宝官网...

Linux学习第二枪(yum,vim,g++/gcc,makefile的使用)

前言&#xff1a;在我的上一篇Linux博客我已经讲了基础指令和权限&#xff0c;现在我们来学习如何在Linux上运行和执行代码 目录 一&#xff0c;yum 二&#xff0c;vim 1&#xff09;命令行模式 2&#xff09;插入模式 3&#xff09;底行模式 三&#xff0c;gcc/g 四&a…...

自然语言处理(一):RNN

「循环神经网络」&#xff08;Recurrent Neural Network&#xff0c;RNN&#xff09;是一个非常经典的面向序列的模型&#xff0c;可以对自然语言句子或是其他时序信号进行建模。进一步讲&#xff0c;它只有一个物理RNN单元&#xff0c;但是这个RNN单元可以按照时间步骤进行展开…...

超全总结!大模型算法面试指南(含答案)

大家好&#xff0c;从 2019 年的谷歌 T5 到 OpenAI GPT 系列&#xff0c;参数量爆炸的大模型不断涌现。可以说&#xff0c;LLMs 的研究在学界和业界都得到了很大的推进&#xff0c;尤其去年 11 月底对话大模型 ChatGPT 的出现更是引起了社会各界的广泛关注。 近些年&#xff0…...

前端使用C-lodop 实现循环套打小案例

目录 前言引入js文件小案例 前言 lodop是一个很优秀打印插件&#xff0c;具体的大家可以官网了解&#xff0c;先在官网下载插件&#xff0c;安装在本地&#xff0c;并启动&#xff0c;点击官网下载 引入js文件 //本JS是加载Lodop插件或Web打印服务CLodop/Lodop7的综合示例&a…...

基于SpringBoot+Vue+mysql卓越导师双选系统设计与实现

博主介绍&#xff1a;✌Csdn特邀作者、博客专家、博客云专家、B站程序阿龙带小白做毕设系列&#xff0c;项目讲解、B站粉丝排行榜前列、专注于Java技术领域和毕业项目实战✌ 系统说明简介&#xff1a; 如今的信息时代&#xff0c;对信息的共享性&#xff0c;信息的流通性有着较…...

Windows 11系统cmd终端美化、Vscode终端美化

win11美化cmd终端和vscode的终端 1. 修改终端背景2. oh-my-posh2.1 安装oh-my-posh2.2 安装Clink2.3 Clink配置oh-my-posh2.4 下载和配置Nerd字体2.5 修改美化主题 3. vscode终端美化 电脑默认的终端没有语法高亮这些&#xff0c;运行命令和代码输出字体一样&#xff0c;有时会…...

[游戏中的图形学实时渲染技术] Part1 实时阴影技术

原理篇&#xff1a; 常见的渲染方程如下&#xff1a; 在不考虑自发光项与考虑阴影对于着色结果的影响之后可以将方程变化为如下形式&#xff1a; 如果射线在到达光源前击中了其他物体时&#xff0c;就认为这条来自光源的光线对着色点没有贡献。 利用上述渲染方程进行正确的着…...

NtripShare Mos地铁自动化监测终端盒子硬件设计

自动化监测产品到目前为止做了接近一年&#xff0c;在软件层面上&#xff0c;控制终端软件、平台软件、网平差算法都已解决&#xff0c;硬件盒子始终是心里过不去的坎&#xff0c;最终还是没有耐住性子自己做了一把。 选型如下&#xff1a; 1、主板:瑞芯微RK3568主板。 2、外…...

第 117 场 LeetCode 双周赛题解

A 给小朋友们分糖果 I 动态规划&#xff1a;设 p [ k ] [ i ] p[k][i] p[k][i] 为将 i i i 个糖果分给 k k k 个小朋友的方案数&#xff0c;先求 p [ 2 ] [ i ] p[2][i] p[2][i] &#xff0c;再求 p [ 3 ] [ n ] p[3][n] p[3][n] class Solution { public:using ll long …...

OpenCV C++ 图像处理实战 ——《多二维码识别》

OpenCV C++ 图像处理实战 ——《多二维码识别》 一、结果演示二、zxing库配置2.1下载编译三、多二维码识别3.1 Method one3.1.1 源码3.2 Method two3.2.1 源码四、源码测试图像下载总结一、结果演示 </...

经典算法(查找与排序)

查找 顺序查找 顺序查找&#xff08;Linear Search&#xff09;是一种在有序数组中查找目标元素的基本算法。它的时间复杂度为 O(n)&#xff0c;适用于查找少量数据。顺序查找的基本思想是从数组的第一个元素开始&#xff0c;逐个与待查找的元素进行比较&#xff0c;直到找到…...

微软和Red Hat合体:帮助企业更方便部署容器

早在2015年&#xff0c;微软就已经和Red Hat达成合作共同为企业市场开发基于云端的解决方案。时隔两年双方在企业市场的多个方面开展更紧密的合作&#xff0c;今天两家公司再次宣布帮助企业更方便地部署容器。 双方所开展的合作包括在微软Azure上部署Red Hat OpenShift&#xf…...

ZYNQ_project:IP_ram_pll_test

例化MMCM ip核&#xff0c;产生100Mhz&#xff0c;100Mhz并相位偏移180&#xff0c;50Mhz&#xff0c;25Mhz的时钟信号。 例化单口ram&#xff0c;并编写读写控制器&#xff0c;实现32个数据的写入与读出。 模块框图&#xff1a; 代码&#xff1a; module ip_top(input …...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

跨链模式:多链互操作架构与性能扩展方案

跨链模式&#xff1a;多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈&#xff1a;模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展&#xff08;H2Cross架构&#xff09;&#xff1a; 适配层&#xf…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

提升移动端网页调试效率:WebDebugX 与常见工具组合实践

在日常移动端开发中&#xff0c;网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时&#xff0c;开发者迫切需要一套高效、可靠且跨平台的调试方案。过去&#xff0c;我们或多或少使用过 Chrome DevTools、Remote Debug…...

【C++】纯虚函数类外可以写实现吗?

1. 答案 先说答案&#xff0c;可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关

在水泥厂的生产流程中&#xff0c;工业自动化网关起着至关重要的作用&#xff0c;尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关&#xff0c;为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多&#xff0c;其中不少设备采用Devicenet协议。Devicen…...

Ubuntu系统多网卡多相机IP设置方法

目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机&#xff0c;交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息&#xff0c;系统版本&#xff1a;Ubuntu22.04.5 LTS&#xff1b;内核版本…...

数据结构:递归的种类(Types of Recursion)

目录 尾递归&#xff08;Tail Recursion&#xff09; 什么是 Loop&#xff08;循环&#xff09;&#xff1f; 复杂度分析 头递归&#xff08;Head Recursion&#xff09; 树形递归&#xff08;Tree Recursion&#xff09; 线性递归&#xff08;Linear Recursion&#xff09;…...