【在Linux世界中追寻伟大的One Piece】System V共享内存

目录

1 -> System V共享内存

1.1 -> 共享内存数据结构

1.2 -> 共享内存函数

1.2.1 -> shmget函数

1.2.2 -> shmot函数

1.2.3 -> shmdt函数

1.2.4 -> shmctl函数

 1.3 -> 实例代码

2 -> System V消息队列

3 -> System V信号量


1 -> System V共享内存

共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。

示意图:

1.1 -> 共享内存数据结构

struct shmid_ds {struct ipc_perm shm_perm; /* operation perms */int shm_segsz; /* size of segment (bytes) */__kernel_time_t shm_atime; /* last attach time */__kernel_time_t shm_dtime; /* last detach time */__kernel_time_t shm_ctime; /* last change time */__kernel_ipc_pid_t shm_cpid; /* pid of creator */__kernel_ipc_pid_t shm_lpid; /* pid of last operator */unsigned short shm_nattch; /* no. of current attaches */unsigned short shm_unused; /* compatibility */void* shm_unused2; /* ditto - used by DIPC */void* shm_unused3; /* unused */
};

1.2 -> 共享内存函数

1.2.1 -> shmget函数

功能:用来创建共享内存
原型
int shmget(key_t key, size_t size, int shmflg);
参数
key:这个共享内存段名字
size:共享内存大小
shmflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的
返回值:成功返回一个非负整数,即该共享内存段的标识码;失败返回-1

1.2.2 -> shmot函数

功能:将共享内存段连接到进程地址空间
原型
void *shmat(int shmid, const void *shmaddr, int shmflg);
参数
shmid: 共享内存标识
shmaddr:指定连接的地址
shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY
返回值:成功返回一个指针,指向共享内存第一个节;失败返回-1

说明:

shmaddr为NULL,核心自动选择一个地址
shmaddr不为NULL且shmflg无SHM_RND标记,则以shmaddr为连接地址。
shmaddr不为NULL且shmflg设置了SHM_RND标记,则连接的地址会自动向下调整为SHMLBA的整数倍。公式:shmaddr -
(shmaddr % SHMLBA)
shmflg=SHM_RDONLY,表示连接操作用来只读共享内存

1.2.3 -> shmdt函数

功能:将共享内存段与当前进程脱离
原型
int shmdt(const void *shmaddr);
参数
shmaddr: 由shmat所返回的指针
返回值:成功返回0;失败返回-1
注意:将共享内存段与当前进程脱离不等于删除共享内存段

1.2.4 -> shmctl函数

功能:用于控制共享内存
原型
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数
shmid:由shmget返回的共享内存标识码
cmd:将要采取的动作(有三个可取值)
buf:指向一个保存着共享内存的模式状态和访问权限的数据结构
返回值:成功返回0;失败返回-1
命令说明
IPC_STAT把shmid_ds结构中的数据设置为共享内存的当前关联值
IPC_SET在进程有足够权限的前提下,把共享内存的当前关联值设置为shmid_ds数据结构中给出的值
IPC_RMID删除共享内存段

 1.3 -> 实例代码

测试代码结构

# ls
client.c comm.c comm.h Makefile server.c
# cat Makefile
.PHONY:all
all:server client
client:client.c comm.c
gcc -o $@ $^
server:server.c comm.c
gcc -o $@ $^
.PHONY:clean
clean:
rm -f client server

comm.h

#ifndef COMM_H
#define COMM_H
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define PATHNAME "."
#define PROJ_ID 0x6666
int createShm(int size);
int destroyShm(int shmid);
int getShm(int size);
#endif

comm.c

#include "comm.h"static int commShm(int size, int flags)
{key_t _key = ftok(PATHNAME, PROJ_ID);if (_key < 0) {perror("ftok");return -1;}int shmid = 0;if ((shmid = shmget(_key, size, flags)) < 0) {perror("shmget");return -2;}return shmid;
}int destroyShm(int shmid)
{if (shmctl(shmid, IPC_RMID, NULL) < 0) {perror("shmctl");return -1;}return 0;
}int createShm(int size)
{return commShm(size, IPC_CREAT | IPC_EXCL | 0666);
}int getShm(int size)
{return commShm(size, IPC_CREAT);
}

server.c

#include "comm.h"int main()
{int shmid = createShm(4096);char* addr = shmat(shmid, NULL, 0);sleep(2);int i = 0;while (i++ < 26) {printf("client# %s\n", addr);sleep(1);}shmdt(addr);sleep(2);destroyShm(shmid);return 0;
}

client.c

#include "comm.h"int main()
{int shmid = getShm(4096);sleep(1);char* addr = shmat(shmid, NULL, 0);sleep(2);int i = 0;while (i < 26) {addr[i] = 'A' + i;i++;addr[i] = 0;sleep(1);}shmdt(addr);sleep(2);return 0;
}

ctrl+c终止进程,再次重启。

2 -> System V消息队列

System V消息队列是一种进程间通信(IPC)机制,它允许进程通过消息的形式进行数据交换。消息队列由内核管理,可以存储多种类型的消息,并且支持消息的有序存取。每个消息都有一个类型字段,接收进程可以根据消息类型来接收特定的消息。

消息队列的关键数据结构

消息队列的状态和配置信息存储在struct msqid_ds数据结构中,它包含了队列的权限、消息计数、最大消息大小、队列字节数、最近操作进程的PID等信息。

消息队列的创建与操作

  • 创建或打开消息队列使用msgget函数,该函数接受一个键值(key)和标志(msgflg)作为参数。如果消息队列不存在且msgflg包含IPC_CREAT标志,则会创建一个新的消息队列。
  • 向消息队列发送消息使用msgsnd函数,接收消息使用msgrcv函数。这些函数允许进程指定消息的类型和大小,以及接收消息时的行为(例如阻塞或非阻塞)。
  • 控制消息队列的状态,如删除消息队列或获取消息队列的统计信息,使用msgctl函数。

消息队列的编程示例

在编程实践中,可以通过创建发送进程和接收进程来演示消息队列的使用。发送进程将数据封装成消息并发送到队列,接收进程则从队列中取出消息进行处理。这种模式适用于生产者-消费者场景,其中一个或多个进程产生数据(生产者),另一个或多个进程消费数据(消费者)。

消息队列的实际应用

消息队列不仅限于简单的数据传递,它们还可以用于更复杂的通信模式,如实现信号量或实现更高级的同步机制。在多进程或多线程的应用程序中,消息队列提供了一种灵活且高效的通信手段。

3 -> System V信号量

System V信号量是一种进程间同步机制,它允许多个进程通过对共享资源的访问计数来进行协调。信号量可以是二元的(用于互斥),也可以是非负整数(用于资源计数)。System V信号量由内核管理,并通过一系列系统调用来创建、操作和销毁。

System V信号量的关键数据结构

System V信号量的核心数据结构是semid_ds,它包含了信号量集的权限、信号量的值、信号量的状态信息等。每个信号量集中的信号量由sem结构表示,其中包含信号量的当前值和相关的进程计数信息。

System V信号量的创建与操作

创建信号量集使用semget函数,该函数接受一个键值(key)、信号量的数量(nsems)和标志(semflg)作为参数。操作信号量集使用semop函数,该函数接受信号量集的标识符、指向sembuf结构数组的指针以及操作的数量作为参数。sembuf结构定义了对信号量执行的具体操作,如等待(P)或信号(V)操作。

System V信号量的编程示例

在编程中,可以通过定义信号量集、初始化信号量值、执行P和V操作以及最终销毁信号量集来实现进程间同步。例如,一个生产者-消费者问题可以通过信号量来确保生产者不会超过消费者的消费速度,防止缓冲区溢出。

System V信号量的实际应用

System V信号量广泛应用于操作系统中,用于实现进程间的同步和互斥。它们可以用于控制对共享资源的访问,管理进程的执行顺序,以及实现更复杂的同步算法。


感谢各位大佬支持!!!

互三啦!!!

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

成都睿明智科技有限公司抖音电商服务靠谱吗?

在这个电商风起云涌的时代&#xff0c;抖音作为短视频直播的超级流量池&#xff0c;正深刻改变着人们的购物习惯。无数商家蜂拥而至&#xff0c;渴望在这片蓝海中找到属于自己的岛屿。而提及抖音电商服务&#xff0c;成都睿明智科技有限公司无疑是一个备受瞩目的名字。那么&…

掌控物体运动艺术:图扑 Easing 函数实践应用

现如今&#xff0c;前端开发除了构建功能性的网站和应用程序外&#xff0c;还需要创建具有吸引力且尤为流畅交互的用户界面&#xff0c;其中动画技术在其中发挥着至关重要的作用。在数字孪生领域&#xff0c;动画的应用显得尤为重要。数字孪生技术通过精确模拟现实世界中的对象…

OpenCV与AI深度学习 | YOLOv11来了:将重新定义AI的可能性

本文来源公众号“OpenCV与AI深度学习”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;YOLOv11来了&#xff1a;将重新定义AI的可能性 Ultralytics YOLOv11的问世标志着人工智能领域&#xff0c;尤其是计算机视觉领域的一个突破性时…

quiz: python网络爬虫之规则1

下面答错了&#xff1a; B c 8A&#xff0c; 9A

大数据-152 Apache Druid 集群模式 配置启动【下篇】 超详细!

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

Golang | Leetcode Golang题解之第440题字典序的第K小数字

题目&#xff1a; 题解&#xff1a; func getSteps(cur, n int) (steps int) {first, last : cur, curfor first < n {steps min(last, n) - first 1first * 10last last*10 9}return }func findKthNumber(n, k int) int {cur : 1k--for k > 0 {steps : getSteps(cu…

MongoDB微服务部署

一、安装MongoDB 1.在linux中拉去MongoDB镜像文件 docker pull mongo:4.4.18 2. 2.创建数据挂载目录 linux命令创建 命令创建目录: mkdir -p /usr/local/docker/mongodb/data 可以在sshclient工具查看是否创建成功。 进入moogodb目录&#xff0c;给data赋予权限777 cd …

交通场景多目标检测系统源码分享

交通场景多目标检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Comput…

【机器学习】13-决策树2——决策树生成、剪枝

机器学习13-决策树2——决策树生成、剪枝 数据集划分为子集&#xff0c;构建出一棵树状结构。 文章目录 机器学习13-决策树2——决策树生成、剪枝前言1. 信息增益&#xff08;ID3算法&#xff09;&#xff08;Iterative Dichotomiser 3&#xff09;&#xff1a;选择信息增益最…

Qemu开发ARM篇-7、uboot以及系统网络连接及配置

文章目录 1、uboot及linux版本网络设置1、宿主机虚拟网卡创建2、uboot使用tap0网卡3、启动测试 2、访问外网设置 在上一篇Qemu开发ARM篇-6、emmc/SD卡AB分区镜像制作并通过uboot进行挂载启动中&#xff0c;我们制作了AB分区系统镜像&#xff0c;并成功通过uboot加载kernel以及d…

详解Java中的Collection单列集合(从底层到用法超详细解析和细节分析)

⭕在 Java 中&#xff0c;集合框架是开发过程中最常用的数据结构之一&#xff0c;其中 Collection 接口是整个集合框架的基础。Collection 是处理单列数据的接口&#xff0c;它定义了一些通用的操作&#xff0c;允许对一组对象进行操作。今天我们将深入介绍 Java 中的单列集合 …

docker学习笔记(1.0)

docker命令 下载镜像相关命令 检索&#xff1a;docker search 比如&#xff1a;docker search nginx 是查看有没有nginx镜像 后面的OK表示是不是官方镜像&#xff0c;如果有就是官方镜像&#xff0c;如果没有就是第三方的。 下载&#xff1a;docker pull 比如&#xff1a…

【09】纯血鸿蒙HarmonyOS NEXT星河版开发0基础学习笔记-Class类基础全解(属性、方法、继承复用、判断)

序言&#xff1a; 本文详细讲解了关于我们在程序设计中所用到的class类的各种参数及语法。 笔者也是跟着B站黑马的课程一步步学习&#xff0c;学习的过程中添加部分自己的想法整理为笔记分享出来&#xff0c;如有代码错误或笔误&#xff0c;欢迎指正。 B站黑马的课程链接&am…

Windows开发工具使用技巧

在 Windows 上进行开发时&#xff0c;有许多工具和技巧可以提升开发效率和用户体验。以下是一些常用的开发工具和技巧&#xff1a; 常用开发工具 1. Visual Studio Code (VS Code) - 插件管理&#xff1a;利用扩展市场&#xff08;Extension Marketplace&#xff09;安装各种…

centos磁盘逻辑卷LVM创建

centos磁盘逻辑卷LVM创建 一、磁盘逻辑卷LVM说明二、centos磁盘使用情况三、LVM安装指南1.LVM工具安装1. yum list lvm2. yum search lvm3. yum search pvcreate4. yum list lvm25. yum install lvm2 2.创建物理卷2.1磁盘情况查看2.2创建物理卷&#xff08;PV&#xff09; 3.创…

【CKA】一、基于角色的访问控制-RBAC

1、基于角色的访问控制-RBAC 1. 考题内容&#xff1a; 2. 答题思路&#xff1a; 这道题就三条命令&#xff0c;建议直接背熟就行。 也可以查看帮助 kubectl create clusterrole -h kubectl create serviceaccount -h kubectl create rolebinding -h 注意&#xff1a; 1、资…

windows 桌面采集音频

头文件&#xff1a; #ifndef __CAPTURE_AUDIO__ #define __CAPTURE_AUDIO__#include <functional> #include <windows.h> #pragma comment(lib, "winmm.lib")class CaptureAudio { public:CaptureAudio();~CaptureAudio();public:bool Init(const std::…

uniapp中uni.request的统一封装 (ts版)

文章目录 前言一、我们为什么要去封装&#xff1f;二、具体实现1.创建一个请求封装文件&#xff1a;2.封装 uni.request&#xff1a;3.如何去使用&#xff1f; 总结 前言 在uniapp中如何去更简洁高效的发送我们的请求&#xff0c;下面就介绍了uni.request()二次封装。 一、我们…

C++ | Leetcode C++题解之第446题等差数列划分II-子序列

题目&#xff1a; 题解&#xff1a; class Solution { public:int numberOfArithmeticSlices(vector<int> &nums) {int ans 0;int n nums.size();vector<unordered_map<long long, int>> f(n);for (int i 0; i < n; i) {for (int j 0; j < i;…

音视频入门基础:FLV专题(7)——Tag header简介

一、引言 从《音视频入门基础&#xff1a;FLV专题&#xff08;3&#xff09;——FLV header简介》中可以知道&#xff0c; 在FLV header之后&#xff0c;FLV文件剩下的部分应由PreviousTagSize和Tag组成。FLV文件 FLV header PreviousTagSize0 Tag1 PreviousTagSize1 Ta…