进程间通信III·System V 系列(linux)

article/2025/6/22 6:40:03

目录

为什么有system V

共享内存

原理

操作

shmget 创建共享内存

shmctl 控制共享内存

shmat 挂接共享内存到进程的虚拟地址空间中

shmdt 将共享内存去关联

特点

模拟练习

Makefile

client.cpp

server.cpp

main.hpp

小知识


为什么有system V

linux是一种类unix系统,管道(文件级进程间通信方案)只对于linux来说合适,对于其他类unix系统不一定适合,所以要有系统级别的进程间通信方案,就是system V

System V 分三种 :共享内存  消息队列  信号量

共享内存

原理

在物理内存中开辟内存块,将物理内存地址映射页表到两个进程的虚拟地址空间中,这样两个进程就都可以看到这份资源,满足进程间通信条件.

操作

shmget 创建共享内存

参数中: 

size: 表示共享内存的大小,以字节为单位(建议是4096的整数倍)

key: 1.是用户传入的一个用来区分不同共享内存的键值(给操作系统使用)

2.用户可以通过ftok系统调用,通过算法形成一个key(将用户传入的pathname和id合并),用户可

以随便传入,只需保证不重复就可以.

shmflg: 共享内存的标志位(传宏),同时可以传权限

创建用的宏有两个:

1.IPC_CREAT 单独使用,如果创建的共享内存不存在,创建,存在就获取shmid并返回

2.IPC_EXCL 单独使用无意义

两者组合使用:如果共享内存不存在,创建,存在,出错返回

返回值: 

成功返回合法的内存标识符(shmid),失败返回-1

 

shmid: 供用户使用的标识共享内存的标识符

shmctl 控制共享内存

参数: 

shmid: 内存标识符,用户使用的

cmd: 传宏表示功能使用

常用:

删除传IPC_RMID

获取传IPC_STAT

buf: 一个输出型参数,当获取共享内存时使用,共享内存的数据就会被保存到这个shmid_ds结构体对象中.

返回值:

失败返回-1(并设置errno错误信息),成功返回值0

shmat 挂接共享内存到进程的虚拟地址空间中

参数:

shmaddr:指明共享内存映射到虚拟地址空间的位置,一般不需要自己指明。

shmflg: 指定进程对共享内存的访问权限,一般传0缺省使用该共享内存的权限。

返回值:

成功返回共享内存映射的虚拟地址,失败返回(void*)-1

判断时要强转,记得64位系统下,void*指针为8字节,所以int强转会损失数据,使用long long int强转

shmdt 将共享内存去关联

返回值:

成功返回0,失败返回-1

特点

1.共享内存默认映射到共享区,访问时不需要系统调用,直接向虚拟地址写入就行.

2.生命周期不随进程,进程结束不会自动回收,随内核


3.使用共享内存时,一定是一个进程创建,一个进程获取,否则两方都去创建,无法通信。


4.是所有IPC中速度最快的,直接向虚拟地址进行写入写出,即减少了数据拷贝次数,又无需使用系统调用(系统调用是有成本的)


5.缺点:没有同步/互斥机制,来对多个进程的访问进行协同,会带来并发问题,

模拟练习

Makefile

.PHONY:all

all:server client

server:server.cpp

    g++ -o $@ $^ -std=c++11

client:client.cpp

    g++ -o $@ $^ -std=c++11

.PHONY:clean

clean:

    rm -f server client

client.cpp

#include "main.hpp"


 

int main()

{

    Shm c_shm;

    c_shm.create();

    c_shm.attach();

    while(1)

    {

        char ch;

        cout<<"请写入字符:";

        cin>>ch;

        c_shm.add(ch);

    }

    c_shm.detach();

    return 0;

}

server.cpp

#include "main.hpp"


 

int main()

{

    Shm s_shm;

    s_shm.create();

    s_shm.attach();

    while(1)

    {

        char ch = '0';

        bool read_ret = s_shm.read(ch);

        if(read_ret)

            cout<<"读到了:"<<ch<<endl;

    }

    s_shm.detach();

    return 0;

}

main.hpp

#pragma once

#include <iostream>

#include <string>

#include <unistd.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>


 

using namespace std;

#define ERR_EXIT(x)\

do{\

    perror(x);\

    exit(EXIT_FAILURE);\

}while(0)

#define SIZE 4096

#define Mode 0666

class Shm

{

    int _shmid;

    void * _start_addr;

    int _index = 4;

public:

    Shm()

    {}    

    bool create()

    {

        key_t ftokret = ftok("shm",6);

        _shmid = shmget(ftokret,SIZE,IPC_CREAT|Mode);

        if(_shmid<0)

        {

            ERR_EXIT("shmget");

        }

        return true;

    }

    bool attach()

    {

        _start_addr = shmat(_shmid,NULL,0);

        if((long long int)_start_addr==-1)

        {

            ERR_EXIT("shmat");

        }

        return true;

    }

    bool detach()

    {

        int shmdtret = shmdt(_start_addr);

        if(shmdtret==-1)

        {

            ERR_EXIT("shmdt");

        }

        return true;

    }

    void add(char ch)

    {

        if(((int*)_start_addr)[0]<SIZE-4)

        {

            ((char*)_start_addr)[_index++] = ch;

            (*(int*)_start_addr)++;

        }

    }

    bool read(char& ch)

    {

        if(_index-4<*(int*)_start_addr)

            ch = ((char*)_start_addr)[_index++];

        else

            return false;

        return true;    

    }

    ~Shm()

    {

        int shmctlret = shmctl(_shmid,IPC_RMID,nullptr);

        if(shmctlret<0)

        {

            ERR_EXIT("shmctl_delete");

        }

    }

};

小知识

1.ipcs -m 命令行指令,查看共享内存


2.ipcrm -m shmid 删除共享内存


3.关于申请空间:内核申请空间必是4kb的整数倍,就算用户开4097个字节,那么内核就会开2*4096个字节大小空间。


http://www.hkcw.cn/article/QShRwckwYy.shtml

相关文章

Kafka 如何保证顺序消费

在消息队列的应用场景中&#xff0c;保证消息的顺序消费对于一些业务至关重要&#xff0c;例如金融交易中的订单处理、电商系统的库存变更等。Kafka 作为高性能的分布式消息队列系统&#xff0c;通过巧妙的设计和配置&#xff0c;能够实现消息的顺序消费。接下来&#xff0c;我…

数据结构:栈(Stack)和堆(Heap)

目录 内存&#xff08;Memory&#xff09;基础 程序是如何利用主存的&#xff1f; &#x1f3af; 静态内存分配 vs 动态内存分配 栈&#xff08;stack&#xff09; 程序执行过程与栈帧变化 堆&#xff08;Heap&#xff09; 程序运行时的主存布局 内存&#xff08;Memo…

数字权限管理(DRM):保护数字内容安全的小卫士

《数字权限管理&#xff08;DRM&#xff09;&#xff1a;保护数字内容安全的小卫士》 在当今数字化飞速发展的时代&#xff0c;我们每天都在和各种各样的数字内容打交道&#xff0c;像电子书、音乐、电影、软件等等。然而&#xff0c;这些数字内容的版权保护和访问控制也成为了…

进程同步:生产者-消费者 题目

正确答案&#xff1a; 问题类型&#xff1a; 经典生产者 - 消费者问题 同时涉及同步和互斥。 同步&#xff1a;生产者与消费者通过信号量协调生产 / 消费节奏&#xff08;如缓冲区满时生产者等待&#xff0c;空时消费者等待&#xff09;。互斥&#xff1a;对共享缓冲区的访问需…

【第三十八周】BLIP-2:一种高效的视觉语言预训练框架

BLIP-2 摘要Abstract文章信息引言方法模型结构Stage1:表征学习Stage2:生成学习模型预训练 实验结果总结 摘要 本篇博客介绍了BLIP-2 &#xff0c;这是一种面向通用多模态任务的高效视觉语言预训练框架&#xff0c;其核心思想是在冻结大语言模型的前提下&#xff0c;通过引入一…

算法打卡12天

19.链表相交 &#xff08;力扣面试题 02.07. 链表相交&#xff09; 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交**&#xff1a;** 题目数据…

Redis最佳实践——安全与稳定性保障之连接池管理详解

Redis 在电商应用的连接池管理全面详解 一、连接池核心原理与架构 1. 连接池工作模型 #mermaid-svg-G7I3ukCljlJZAXaA {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-G7I3ukCljlJZAXaA .error-icon{fill:#552222;}…

无人机+AI视频联网:精准狙击,让‘罪恶之花’无处藏身

引言&#xff1a;禁毒攻坚战&#xff0c;科技是关键 今天是2025年5&#xff0c;正值罂粟等毒株生长关键期。传统人工巡查耗时长、盲区多&#xff0c;而无人机巡检视频AI分析的智慧禁毒方案&#xff0c;正以“高空鹰眼地面AI”的立体化监控网络&#xff0c;实现毒株种植的早发现…

以太网原理与开发802.3

W5500以太网搭建 官方移植库W5500 下载地址:GitCode - 全球开发者的开源社区,开源代码托管平台目录结构Ethernet以太网移植文件文件wizchip_conf 配置 芯片型号 工作模式 wizchip_conf.c配置 临界区片选SPI收发字节配置 自定义注册SPI // 自定义注册SPI相关回调函数 void use…

day5 cpp:,对象的组织(const对象),

1.对象的组织(类比内置类型) const对象 const对象只能调用const成员函数和数据成员&#xff0c;除了四大金刚 若成员函数没有加const(void print() const{}),即便里面没有_ix100修改值&#xff0c;也不能pt2.print()访问&#xff0c;因为是const Point pt2(3,5)--->对象不…

C语言进阶--动态内存管理

学习数据结构重要的三个部分&#xff1a;指针、结构体、动态内存管理&#xff08;malloc、calloc、realloc、free&#xff09;。 1.为什么存在动态内存分配&#xff1f; 1.空间开辟大小是固定的&#xff1b; 2.数组在声明时&#xff0c;必须指定数组的长度&#xff0c;它所需…

Excel如何去除公式保留数值

我们有时候使用Excel在修改一部分数值的时候会导致和该数值相关的通过公式进行计算的数值发生变化&#xff0c;但有时我们不想改变这些数值&#xff0c;同样的有时我们在移动一些数值的时候会导致通过这些数值计算的数值变为#!VALUE&#xff0c;这是我们不想发生的&#xff0c;…

C++学习-入门到精通【11】输入/输出流的深入剖析

C学习-入门到精通【11】输入/输出流的深入剖析 目录 C学习-入门到精通【11】输入/输出流的深入剖析一、流1.传统流和标准流2.iostream库的头文件3.输入/输出流的类的对象 二、输出流1.char* 变量的输出2.使用成员函数put进行字符输出 三、输入流1.get和getline成员函数2.istrea…

一周学会Pandas2之Python数据处理与分析-数据重塑与透视-melt() - 融化 / 逆透视 (宽 -> 长)

锋哥原创的Pandas2 Python数据处理与分析 视频教程&#xff1a; 2025版 Pandas2 Python数据处理与分析 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili melt() 是 pandas 中用于数据重塑的核心方法之一&#xff0c;它可以将 宽格式数据 转换为 长格式数据&#xff0c;特…

设计模式——工厂方法模式(创建型)

摘要 工厂方法模式是一种创建型设计模式&#xff0c;通过定义创建对象的接口&#xff0c;让子类决定实例化哪个类。它包含抽象产品、具体产品、抽象工厂和具体工厂等角色。该模式使类的实例化延迟到子类&#xff0c;具有良好的扩展性和灵活性&#xff0c;适用于多种场景&#…

软件性能之CPU

性能是个宏大而驳杂话题&#xff0c;从代码&#xff0c;到网络&#xff0c;到实施&#xff0c;方方面面都会涉及到性能问题&#xff0c;网上对性能讲解的文章多如牛毛&#xff0c;从原理到方法再到工具都有详细的介绍&#xff0c;本文虽不能免俗&#xff0c;但期望能从另外一个…

腾讯云推出云开发AI Toolkit,国内首个面向智能编程的后端服务

5月28日&#xff0c;腾讯云开发 CloudBase 宣布推出 AI Toolkit&#xff08;CloudBase AI Toolkit&#xff09;&#xff0c;这是国内首个面向智能编程的后端服务&#xff0c;适配 Cursor 等主流 AI 编程工具。 云开发 AI Toolkit旨在解决 AI 辅助编程的“最后一公里”问题&…

当前用户的Git本地配置情况:git config --local --list

通过config命令可以查询当前用户的本地配置情况。这些配置项定义了 Git 在当前仓库中的行为&#xff0c;包括文件权限处理、符号链接处理以及大小写敏感性等。 git config --local --list core.repositoryformatversion0 指定 Git 仓库的格式版本。版本 0 是最初的格式。 cor…

修改 vscode 左侧导航栏的文字大小 (更新版)

1. 起因&#xff0c; 目的: 问题&#xff1a; vscode 左侧的文字太小了&#xff01;&#xff01;&#xff01;我最火的一篇文章&#xff0c;写的就是这个问题。 看来这个问题&#xff0c;是很广泛的一个痛点。我最近更新了 vscode&#xff0c; 这个问题又出现了。再来搞一下。…

Python训练第四十天

DAY 40 训练和测试的规范写法 知识点回顾&#xff1a; 彩色和灰度图片测试和训练的规范写法&#xff1a;封装在函数中展平操作&#xff1a;除第一个维度batchsize外全部展平dropout操作&#xff1a;训练阶段随机丢弃神经元&#xff0c;测试阶段eval模式关闭dropout 昨天我们介绍…