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

news2024/11/16 7:32:44

目录

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.coloradmin.cn/o/2185051.html

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

相关文章

K8S部署流程

一、war打包镜像(survey,analytics,trac系统) 代码打包成war准备tomcat的server.xml文件&#xff0c;修改connector中8080端口为项目的端口 修改前&#xff1a; <Connector port"8080" protocol"HTTP/1.1"connectionTimeout"20000"redirect…

idea环境下vue2升级vue3

在IDEA环境下&#xff0c;Vue2升级Vue3是一个非常重要的主题。在本文中&#xff0c;我们将介绍Vue2和Vue3之间的主要区别&#xff0c;以及如何在IDEA中升级Vue2项目到Vue3。我们还将讨论Vue3的新特性&#xff0c;如Composition API和Teleport等&#xff0c;并提供一些实用的代码…

快速掌握-vue3

是什么 vue2 的升级版&#xff0c; 使用 ts 重构了代码&#xff0c; 带来了 Composition API RFC。 类似于 react hook 的写法。 ts 重构&#xff0c;代码可读性更强vue3.x 使用 Proxy 取代 Vue2.x 版本的 Object.defineProperty实现了 TreeShaking (当 Javascript 项目达到一定…

自闭症寄宿学校:为孩子发掘多重才能

在教育的广阔天地里&#xff0c;每一片土壤都孕育着不同的生命&#xff0c;每一颗种子都蕴含着无限的可能。对于自闭症儿童而言&#xff0c;他们的世界或许更加独特与复杂&#xff0c;但同样充满了未被发掘的潜能与才华。在广州&#xff0c;星贝育园自闭症儿童寄宿制学校正以满…

计算机毕业设计 Java酷听音乐系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

师生健康信息管理:SpringBoot技术突破

第4章 系统设计 4.1 系统体系结构 师生健康信息管理系统的结构图4-1所示&#xff1a; 图4-1 系统结构 登录系统结构图&#xff0c;如图4-2所示&#xff1a; 图4-2 登录结构图 师生健康信息管理系统结构图&#xff0c;如图4-3所示。 图4-3 师生健康信息管理系统结构图 4.2…

【Linux】用虚拟机配置Ubuntu环境

目录 1.虚拟机安装Ubuntu系统 2.Ubuntu系统的网络配置 3.特别声明 首先我们先要下载VMware软件&#xff0c;大家自己去下啊&#xff01; 1.虚拟机安装Ubuntu系统 我们进去之后点击创建新的虚拟机&#xff0c;然后选择自定义 接着点下一步 再点下一步 进入这个界面之后&…

element-ui 通过按钮式触发日期选择器

element ui 写在前面1. 自定义的日期时间组件CustomDatePicker.vue2. 页面效果总结写在最后 写在前面 需求&#xff1a;elementui中日期时间选择器&#xff0c;目前只能通过点击input输入框触发日期选择器&#xff0c;我希望能通过其他方式触发日期选择器同时把input输入框去掉…

Spring的IOC和DI入门案例分析和实现

前言 IOC和DI是spring的核心之一&#xff0c;那我们为什么要使用spring技术呢&#xff1f;spring技术的优点在哪里&#xff1f; spring的特点&#xff1a; 简化开发&#xff0c;降低企业级开发的复杂性框架整合&#xff0c;高效整合其他技术&#xff0c;提高企业级应用的开发与…

【Python报错已解决】TypeError: ‘NoneType‘ object is not callable

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 专栏介绍 在软件开发和日常使用中&#xff0c;BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

【常读常悟】《大数据之路-阿里巴巴大数据实践》一书读书摘要

【常读常悟】《大数据之路-阿里巴巴大数据实践》一书读书摘要 1、背景2、目录结构3、数据加工链路4、章节摘要4.1 第2章 日志采集4.1.1 日志采集方案4.1.2 采集指标 4.2 第3章 数据同步4.2.1 数据的特点4.2.2 数据同步的三种方式4.2.3 数据同步的最佳实践 4.3 第4章 离线数据开…

LabVIEW自动生成NI-DAQmx代码

在现代数据采集和控制系统中&#xff0c;LabVIEW被广泛应用于各种工业和科研领域。其中&#xff0c;NI-DAQmx是一个强大的驱动程序&#xff0c;可以帮助用户高效地管理和配置数据采集任务。本文将介绍如何在LabVIEW中通过DAQ Assistant Express VI和任务常量自动生成NI-DAQmx代…

VBA字典与数组第十九讲:VBA中动态数组的定义及创建

《VBA数组与字典方案》教程&#xff08;10144533&#xff09;是我推出的第三套教程&#xff0c;目前已经是第二版修订了。这套教程定位于中级&#xff0c;字典是VBA的精华&#xff0c;我要求学员必学。7.1.3.9教程和手册掌握后&#xff0c;可以解决大多数工作中遇到的实际问题。…

【论文笔记】Visual Instruction Tuning

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: Visual Instruction Tunin…

Linux线程(二)线程ID及创建线程详解

1.线程ID 就像每个进程都有一个进程 ID 一样&#xff0c;每个线程也有其对应的标识&#xff0c;称为线程 ID。进程 ID 在整个系统中是唯一的&#xff0c;但线程 ID 不同&#xff0c;线程 ID 只有在它所属的进程上下文中才有意义。 进程 ID 使用 pid_t 数据类型来表示&#xf…

【Linux进程间通信】Linux匿名管道详解:构建进程间通信的隐形桥梁

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;Linux “ 登神长阶 ” &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀Linux进程间通信 &#x1f4d2;1. 进程间通信介绍&#x1f4da;2. 什么是管道&#x1f4dc;3…

22.1 k8s不同role级别的服务发现

本节重点介绍 : 服务发现的应用3种采集的k8s服务发现role 容器基础资源指标 role :nodek8s服务组件指标 role :endpoint部署在pod中业务埋点指标 role :pod 服务发现的应用 所有组件将自身指标暴露在各自的服务端口上&#xff0c;prometheus通过pull过来拉取指标但是promet…

期权卖方如何选择铁矿石行权价?期权策略盈亏分析计算方式详解

截止9月30日收盘&#xff0c;铁矿石2411合约收盘价825元/吨。日线级别处于上涨趋势中 假设以825元为最新价&#xff0c;假设后市铁矿石期货价格会下跌&#xff0c;期权卖方应该如何选择行权&#xff1f; 卖出行权价800的看涨期权&#xff0c;期权报价37.9&#xff0c;一手权利…

【环境配置】科研小白Windows下安装Git

2024年小白使用Win10安装Git 2.46.2教程&#xff1a; 1 下载安装包 访问下载地址 Git - Downloading Package (git-scm.com) 下载之后打开文件 2 安装过程 点击Next 2.1 选择安装路径 2.2 选择勾选必要组件 2.3 一路Next 这一步直接Next即可 继续点击Next 继续点击Ne…