#include <sys/ipc.h>
#include <sys/shm.h>
#if 0
如何防止共享内存访问冲突:
如果是mmap一个文件的方式,就要注意是否原来的数据被sync了再写新的数据。跟读DMA要先回写cache一样。
=====
新建或绑定到一块共享内存。
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
key: 用来标识一块共享内存区域。即使用相同的key可访问同一块共享内存。这个key是系统范围的。
size: 共享内存的大小,这个大小是PAGE_SIZE对齐的,即如果你传入3K,该函数也会创建一个4K(页大小)的shm。
shmflg: 可指定一些标志位。
IPC_CREAT 新建一个共享内存块。如果不带这个标记,则shmget()会去寻找key是否已被绑定现有块,以及用户是否有权限访问。
IPC_EXCL 用来与IPC_CREAT配合,来确定一个块是否已经存在。
(mode_flags) shmflg的低9位,表示owner/group/others的的rwx访问权限,目前x(执行)权限没有使用。
SHM_HUGETLB 使用巨页来分配共享内存块的空间(用户需要有CAP_IPC_LOCK权限才能设置该标记)。
SHM_NORESERVE 是否为该共享内存块预留交换分区空间。如果设置的话,系统对内存分配变得严格,可能在物理内存不足时写shm而发生OOM。
如果是新建共享内存,则shmflg需要携带IPC_CREAT标记,如果此时key对应的共享内存块已经存在,则该函数返回失败。
如果shmflg同时设置了IPC_CREAT和IPC_EXCL,并且此时key对应的共享内存块已经存在,则该函数返回错误,errno置为EEXIST。(类似于open()的O_CREAT | O_EXCL标记。)
如果shmflg没有设置IPC_CREAT又想新建,则失败,errno=ENOENT。
如果key的值为IPC_PRIVATE,则shmget不会去理会shmflg除低9bit之外的其他标记,总会新建一个共享内存且创建成功。(如果key已存在呢?应该不会新建吧,不然有毛用啊?)
新建共享内存块时,如果size<SHMMIN或size>SHMMAX,则返回错误,errno=EINVAL。其中SHMMAX可在/proc/sys/kernel/shmmax中查看和修改。
如果key的块已存在,但size大于该内存块的大小,则返回错误,errno=EINVAL。size可以小于key块的大小,说明该进程只想共享前size大小的部分。
新创建的共享内存块的内容会全部初始化为0。
该函数返回一个标记这块共享内存块的shmid,供进程后续操作这块内存用。如果出错则返回-1。
系统中所有共享内存的大小上限为SHMALL,系统中共享内存块的个数上限为SHMMNI。如果此次调用导致超过这两个限制,都会出错,errno=ENOSPC。
其中SHMALL的值可在/proc/sys/kernel/shmall中查看和修改,单位是page。SHMMNI的值可在/proc/sys/kernel/shmmni中查看和修改。每个进程的shmid个数没有特别限制。
----
将进程关联到共享内存。
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
将shmid(shmget()的返回值)对应的共享内存块关联(attach)到本进程的虚拟地址空间,关联的地址由参数shmaddr指定:
1.如果shmaddr为NULL,则由系统来选择一个未使用的地址。
2.如果shmaddr不为NULL,且shmflg参数设置了SHM_RND,则系统会将shmaddr向前取到与SHMLBA(通常是一页)对齐的地址。如果没有SHM_RND标记,则需要用户自己给shmaddr指定一个页对齐的地址。
3.如果shmflg设置了SHM_REMAP,则shmaddr必须不为NULL,SHM_REMAP意思是在关联该共享内存块的同时,将shmaddr开始size大小的区域中已有的mapping都覆盖掉(如果这段区域的某一段已被映射过,通常会返回EINVAL错误)。
建议shmaddr赋值为NULL,让系统自己确定映射的地址,在兼容性上更好些,相应的,在attach之后用于访问共享块的指针需是相对shmaddr(shmat()的返回值)的相对地址,而不要是绝对地址。
如果shmflg带了SHM_RDONLY标记,则表示以只读的方式attach到共享块(当然该进程要有对块的读权限),如果没带SHM_RDONLY标记,则表示以读写的方式attach到共享块(当然该进程要有对块的读写权限)。目前没有只写的关联方式。
该函数返回该共享块实际被关联到的地址空间的起始地址,供进程后续访问该块内存用。如果失败,返回(void *) -1,
另外需要说明的几点:
-关联一个块并不会增加进程堆的大小(共享内存是通过匿名文件来创建的),在进程退出时,会自动解除与该块的关联关系。
-在一个进程中,你可以通过shmat()多次关联同一个共享块,例如一处关联成只读,另一处关联为读写,这样也会相应的映射两块不同的虚拟地址空间。
-在进程调用fork()后,子进程会继承父进程已经attach的共享内存块。在进程调用execve()或_exit()后,该进程所有attach的共享内存块都会被detach掉。
#include <sys/types.h>
#include <sys/shm.h>
int shmdt(const void *shmaddr);
解除该进程与shmaddr指定的共享块的关联关系,shmaddr即为shmat()的返回值。
解绑成功返回0,失败返回-1。如果指定的shmaddr并没有关联到一个共享块,或者shmaddr没有页对齐,都会返回错误,errno=EINVAL。
注意,每个共享内存块都会在标准库中维护一个shmid_ds结构,该结构也用来与内核态(shm_ids[]结构)交互,其中的shm_nattch成员是一个引用计数器,被attach就+1,被detach就-1,当shm_nattch被减到0,该共享内存块就被销毁了。
#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
控制共享内存块shmid的属性。要修改的属性和属性内容分别由cmd和buf指定。
buf是指向struct shmid_ds结构的指针:
struct shmid_ds {
struct ipc_perm shm_perm; /* Ownership and permissions */
size_t shm_segsz; /* Size of segment (bytes) */
time_t shm_atime; /* Last attach time */
time_t shm_dtime; /* Last detach time */
time_t shm_ctime; /* Last change time */
pid_t shm_cpid; /* PID of creator */
pid_t shm_lpid; /* PID of last shmat(2)/shmdt(2) */
shmatt_t shm_nattch; /* No. of current attaches */
...
};
struct ipc_perm {
key_t __key; /* Key supplied to shmget(2) */
uid_t uid; /* Effective UID of owner */
gid_t gid; /* Effective GID of owner */
uid_t cuid; /* Effective UID of creator */
gid_t cgid; /* Effective GID of creator */
unsigned short mode; /* Permissions + SHM_DEST and
SHM_LOCKED flags */
unsigned short __seq; /* Sequence number */
};
cmd可取的值:
IPC_STAT 获取共享内存块的状态,是一个struct shmid_ds结构,保存在参数buf中。
IPC_SET 设置共享内存块的某些属性,包括shm_perm.uid, shm_perm.gid和shm_perm.mode的低9bit权限位,同时会更新shm_ctime。
IPC_RMID 标记该共享内存块将被销毁(实际销毁仍在最后一个进程detach之后)。
IPC_INFO 获取系统中一些共享内存的限制。结果由buf返回(struct shminfo结构),因此这时要将buf强制类型转换一下。
struct shminfo {
unsigned long shmmax; /* Maximum segment size */
unsigned long shmmin; /* Minimum segment size;
always 1 */
unsigned long shmmni; /* Maximum number of segments */
unsigned long shmseg; /* Maximum number of segments
that a process can attach;
unused within kernel */
unsigned long shmall; /* Maximum number of pages of
shared memory, system-wide */
};
SHM_INFO 获取系统中共享内存对物理内存的消耗情况,结果是struct shm_info结构。
struct shm_info {
int used_ids; /* # of currently existing
segments */
unsigned long shm_tot; /* Total number of shared
memory pages */
unsigned long shm_rss; /* # of resident shared
memory pages */
unsigned long shm_swp; /* # of swapped shared
memory pages */
unsigned long swap_attempts;
/* Unused since Linux 2.4 */
unsigned long swap_successes;
/* Unused since Linux 2.4 */
};
SHM_STAT 获取共享内存状态,是一个struct shmid_ds结构,保存在参数buf中。和IPC_STAT类似,但此时传入的shmid并不是共享块的id,而是内核内部管理所有共享块的数组的index。
SHM_LOCK 禁止共享块的内存换出到swap分区。
SHM_UNLOCK 允许共享块的内存换出到swap分区。
使用shmctl()进行上述cmd操作的返回值如下:
1. IPC_INFO和SHM_INFO,如果成功,返回shmid对应共享块在内核数组中目前的最高index。这样,就可以与SHM_STAT配合,在当前进程中获得系统中所有共享块的状态。
2. SHM_STAT,如果成功,返回index对应的共享块的shmid。
3. 其他cmd,成功返回0。所有cmd,如果失败都会返回-1并设置errno。
SYNOPSIS
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);
DESCRIPTION
The ftok() function uses the identity of the file named by the given pathname (which must refer
to an existing, accessible file) and the least significant 8 bits of proj_id (which must be
nonzero) to generate a key_t type System V IPC key, suitable for use with msgget(2), semget(2),
or shmget(2).
The resulting value is the same for all pathnames that name the same file, when the same value
of proj_id is used. The value returned should be different when the (simultaneously existing)
files or the project IDs differ.
RETURN VALUE
On success, the generated key_t value is returned. On failure -1 is returned, with errno indi‐
cating the error as for the stat(2) system call.
Of course no guarantee can be given that the resulting key_t is unique. Typically, a best
effort attempt combines the given proj_id byte, the lower 16 bits of the inode number, and the
lower 8 bits of the device number into a 32-bit result. Collisions may easily happen, for
example between files on /dev/hda1 and files on /dev/sda1.
==================
mmap实现共享内存:
mmap() : 将文件或设备映射到用户的虚拟地址空间。
内核中相应的实现了系统调用:
sys_mmap() : 以字节为单位。
sys_mmap2() : 以页为单位。
取消映射:munmap()。
相关的5个系统调用:
#include <sys/mman.h>
void *mmap(void *start, size_t length, int prot, int flags,
int fd, off_t offset); /* arch/mips/kernel/syscall.c: mips_mmap */
int munmap(void *start, size_t length); /* mm/mmap.c */
void * mremap(void *old_address, size_t old_size , size_t new_size, int flags); /* mm/mremap.c */
void * mmap2(void *start, size_t length, int prot,
int flags, int fd, off_t pgoffset); /* arch/mips/kernel/syscall.c: mips_mmap2 */
int remap_file_pages(void *start, size_t size, int prot, ssize_t pgoff, int flags); /* mm/fremap.c */
既然说到脏页,就再多说一句,mmap()映射时有Shared_Dirty和Private_Dirty的概念,大家注意把这里的dirty和脏页区分开,mmap可以映射匿名页和文件,
在映射匿名页时,Shared_Dirty和Private_Dirty是指还没有被msync()或unmap()同步的,这时跟系统的脏页没有任何关系;
而mmap在映射文件时,除了Shared_Dirty和Private_Dirty也会产生脏页,因为产生了写文件。
void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
int munmap(void *addr, size_t length);
#include <sys/mman.h>
int msync(void *addr, size_t length, int flags);
将mmap映射的addr到addr+length的内容写回到磁盘。
注意,addr必须是PAGESIZE的整数倍。
flags参数可以是MS_ASYNC, MS_SYNC, MS_INVALIDATE,但MS_ASYNC和MS_SYNC不能同时置位。MS_ASYNC表示异步,函数立即返回;而MS_SYNC表示同步,函数阻塞直到回写完成。MS_INVALIDATE则将这个文件的其他映射都无效,保证这次回写的内容不被其他映射回写覆盖掉。
回写成功返回0,如果指定内存区域并没有被映射过,返回ENOMEM,如果MS_INVALIDATE置位但这段内存已经被锁住(如mlock()等)了,返回EBUSY。
#include <linux/mman.h>
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <sys/mman.h>
void *mremap(void *old_address, size_t old_size,
size_t new_size, int flags, ... /* void *new_address */);
将已经mmap的内存(old_address和old_size指定)重新进行映射,大小由new_size指定,实际上就是对原映射内存进行扩大或缩小。如果有第五个参数new_address则也同时指定新映射的起始地址。
这和realloc()的含义基本相同,实际上mremap()的一个用途就是实现一个更为高效的realloc(),因为mremap只是修改虚拟页地址到物理地址的映射关系即更新页表。
注意old_address必须是页对齐的。
flags可以是0,也可以置下面两个bit位;
MREMAP_MAYMOVE: 由于默认情况下如果old_address起始地址后没有足够的new_size空闲虚拟地址空间用来映射,mremap就会失败。如果加上MREMAP_MAYMOVE标记,mremap在这种情况下就会找一个新的起始地址来映射new_size大小的内存。
MREMAP_FIXED: 设置这个标记,mremap就会接受第五个参数new_address,强制指定新映射的(页对齐的)起始地址。如果设置了这个标记,那MREMAP_MAYMOVE也必须同时被设置。同时,new_address和new_size这段空间原来已存在的映射都会被unmap掉。
哎?MREMAP_FIXED的时候指定的地址如果后面空间不够,是不是还是会帮你重新选地址??
如果原来的old_address映射区有内存锁(如mlock()),那这个锁也会被集成到新的size或新的location映射区。
函数成功,返回指向新的虚拟地址空间的指针,错误返回MAP_FAILED,即(void *)-1。
注意,new_size不能是0,另外,old_address,old_size和new_address,new_size不能重叠(为啥??)。
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <sys/mman.h>
int remap_file_pages(void *addr, size_t size, int prot,
ssize_t pgoff, int flags);
这个就不看也不翻译了。在csdn里收藏了一篇文章讲的很明白。
===========
我在虚拟机和Hi3520d板子上都没有看到有mmap2(),实际上内核里也没找到(只在powerpc里找到有)。因此不用看了。
#include <sys/mman.h>
void *mmap2(void *addr, size_t length, int prot,
int flags, int fd, off_t pgoffset);
DESCRIPTION
The mmap2() system call operates in exactly the same way as mmap(2),
except that the final argument specifies the offset into the file in
4096-byte units (instead of bytes, as is done by mmap(2)). This enables
applications that use a 32-bit off_t to map large files (up to 2^44
bytes).
RETURN VALUE
On success, mmap2() returns a pointer to the mapped area. On error -1 is
returned and errno is set appropriately.
ERRORS
EFAULT Problem with getting the data from userspace.
EINVAL (Various platforms where the page size is not 4096 bytes.) offset
* 4096 is not a multiple of the system page size.
mmap2() can return any of the same errors as mmap(2).
VERSIONS
mmap2() is available since Linux 2.3.31.
CONFORMING TO
This system call is Linux-specific.
NOTES
Nowadays, the glibc mmap() wrapper function invokes this system call
rather than the mmap(2) system call.
On ia64, the unit for offset is actually the system page size, rather
than 4096 bytes.
--共享内存同步要注意什么--
使用共享内存的时候,除了设计上减少同步,还有别的要注意么?
1,创建任何东西先带着CREAT | EXCL去创建,失败了则直接打开,这是原子性必备的。
2,共享内存初始化之前如何同步?即如何保证创建chm的进程对共享内存初始化好了,其他进程才能够shmget? 设置mode的x位(用shmctl设置IPC_SET,因为x位未使用)后开始初始化共享内存,结束后取消x位,任何进程打开共享内存后stat轮询检查x位(用shmctl获取IPC_STAT)是否复位,复位后才可以开始操作。
3,进程共享的mutex, cond,你应该都会用,不会用看书或者man pthread.h找接口。
4,共享内存可以做成chunk list内存块链表,一般用于在共享内存中建立树型数据结构,或者建死的多级hash表,或者循环队列,都是可以做的。
================
进程间通信的信号量接口: semget, semctl, semop
#endif
相关推荐
基于 CDR 项目的 DeepStream-YOLOv5 机器人视觉接口复现记录1
Demo功能容器状态Demo 1YOLOv5 文件检测cdr_x86已跑通Demo 2共享内存读取检测框cdr_x86已跑通Demo 3ROS topic 输出检测框cdr_x86已跑通Demo 4Gemini 2 USB 摄像头实时检测已跑通。
文件系统核心存储引擎_文件内存映射详解
文件内存映射详解 目录 文件映射应用场景 进程间共享信息 实现文件数据从磁盘到内存的映射,极大的提升应用程序访问文件的速度 进程间通信 - 文件映射原理(mmap函数) 原理:将一个文件或者其它对象映射进内存。 1.使用普通文件提供的内存映射 2.使用特殊文件提供匿名内存映射 ...
F28388D以太网实战:LWIP协议栈移植与EMAC调试全记录
嵌入式以太网通信是设备联网的基础,其核心是TCP/IP协议栈与底层MAC/PHY硬件的高效协同。LWIP作为轻量级开源协议栈,被广泛用于MCU资源受限场景,通过裁剪配置即可实现稳定的网络通信。C2000系列F28388D芯片集成10/100M EMAC外设,配合DP83822 PHY芯片,可构建原生以太网接口。其双核架构下,CM4内核负责跑LWIP协议栈,C28x内核专注实时控制,通过IPC实现数据交换。RMII接口以更少引脚完成百兆通信,是开发板常用接法。从PHY复位时序、DMA描述符管理到lwipopt
Linux进程通信之共享内存
Linux 共享内存
Linux——详解共享内存shared memory_linux 共享内存
共享内存本质上就是内存中的一块区域,用于进程间通信使用。该内存空间由操作系统分配与管理。与文件系统类似的是,操作系统在管理共享内存时,不仅仅有内存数据块,同时还会创建相应结构体来记录该共享内存属性,以便于管理。因此,共享内存不只有一份,可以根据需求申请多个。进程之间进行通信的时候,会获取 到共享内存的地址,写端进程写入数据,读端进程通过直接访问内存完成数据读取。
OpenResty Lua模块配置详解与实践
本文详细介绍了OpenResty中Lua模块的各种配置指令,包括日志记录、负载均衡、SSL握手处理等高级功能。通过具体的代码示例和上下文解释,阐述了如何在Nginx中嵌入Lua脚本来实现复杂的功能,并对Lua代码的执行时机、性能影响和安全性等方面给出了建议。
进程间通信之---共享内存
目录 共享内存: 1. 共享内存的原理 2.共享内存的接口 2.1创建或者获取共享内存接口 2.2将共享内存附加到进程的虚拟地址空间 2.3分离 2.4操作共享内存接口 3.共享内存代码 4.共享内存的特性 共享内存: 1. 共享内存的原理 1.1 在物理内存当中开辟一段空间 1.2不同的进程通过页表将物理内存空间映射到自己的进程虚拟地址空间当中 1.3不用的进程通过操作自己进程虚拟地址空间当中的虚拟地址,来操作共享内存 ..
【软件逆向】带壳带反调试找flag教程(VMProtect3.0+X64dbg+ScyllaHide)
【软件逆向】带壳带反调试找flag教程(VMProtect 3.0+X64dbg+ScyllaHide)
进程间通信之共享内存
进程通信与共享内存
金蝶云星空初级实施认证考题
Q4.[单选题] (1.5分) 总账中的多账簿账表主要是基于什么进行查看的Q47.[多选题] (2.5分) 销售订单的收款计划页签勾选预收之后,预收控制环节可以控制哪些节点?
深度学习基于Resnet18的图像多分类--训练自己的数据集(超详细 含源码)
深度学习基于Resnet18的图像多分类--训练自己的数据集(超详细 含源码)
一个基于共享内存的内存数据库:3 用户接口
一个基于共享内存的内存数据库:3 用户接口
2025东三省D题深圳杯数学建模实战解析:基于多模型融合的法医STR混合样本智能识别系统
本文深入解析了2025年东三省数学建模竞赛D题,即深圳杯赛题,聚焦于法医STR混合样本的智能识别挑战。文章系统阐述了构建一个基于多模型融合的智能识别系统的完整流程,涵盖贡献者人数判定、DNA贡献比例估计、个体基因型推断以及STR谱图去噪四大核心步骤。通过融合高斯混合模型、随机森林、非负矩阵分解、小波变换与深度学习等多种技术,并强调特征工程的重要性,为破解法医DNA混合样本分析这一行业难题提供了清晰的数学建模与AI实战思路。
4、设计共享内存管理接口
设计共享内存管理接口
PMSM控制系列文章进阶-8.电流、角度采样及其同步
摘要:本文分析了高低压电机在电流和角度采样中的不同方案选择。高压电机采用霍尔传感器和旋变进行隔离采样,低压电机则使用shunt电阻和磁编码器以降低成本。重点讨论了采样时间补偿问题:电流采样需与PWM周期同步,角度采样需考虑传感器延迟;通过park变换和反park变换时需补偿采样与发波的时间差,提出了通过测试母线电流或Ud变化来验证补偿时间准确性的方法。文中还介绍了对传感器信号进行软解码处理的方法,包括消除直流偏置、增益误差和正交误差等参数的自学习过程。
金融监管压力测试场景生成
压力测试是一种评估金融资产或机构在极端市场条件下的表现和风险承受能力的方法。它通过模拟各种不利的市场情景,测试金融机构在这些情景下的财务状况和运营能力。压力测试的作用在于帮助金融机构识别潜在风险,评估应对策略,并制定应急预案。总结压力测试场景生成系统的开发过程和实现效果,强调其在金融监管中的重要性和应用价值。随着金融市场的发展,实时压力测试将越来越重要。未来,压力测试需要更加注重实时性和动态性,及时反映市场的变化。本文详细介绍了金融监管压力测试的重要性、核心概念、算法原理、系统架构以及实战案例。
nginx验证码接口被打爆的实战与防护记录
最近线上遇到了一次比较“烧钱”的事故:希望对同样有验证码业务、却还没做完备防护的同学有参考价值。
基于综合阻抗特征的配电架空线路单相断线故障区段定位研究
本文提出了一种基于综合阻抗特征的配电架空线路单相断线故障区段定位方法。通过分析故障后正序、负序阻抗变化,构造综合阻抗判据实现精准定位。仿真结果表明:该方法能有效识别故障区段,差异度判据显著(故障区段达0.508,非故障区段<0.016);对过渡电阻(1-200Ω)和负荷变化具有强鲁棒性,定位准确率不受影响。相比传统方法,综合阻抗法放大了断线故障特征,解决了弱故障信号检测难题,为配电网安全运行提供了可靠的技术手段。
爬虫flask接口打包成docker镜像遇到的问题
selenium selenium.common.exceptions.WebDriverException: Message: unknown error: session deleted because of page crash from unknown error: cannot determine loading status
apple游客下单逆向分析
Apple游客下单Cookies注册激活流程逆向分析与算法实现
假人有限元模型
假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用
Iceoryx整体
记录iceoryx学习过程
C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片
基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正
C接口实现任务记录
C接口实现任务记录 main—>c接口---->c++接口 由c接口的实现记录任务taskID //main.cc # include "c_opt.h" # include <iostream> int main() { int task1 = 11; int task2 = 22; int task3 = 33; //传入taskid用...
汉书HE8,好用的汇编代码编写工具
汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大
NTscan扫描工具
ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。
mfc转QT--sp_serverinfo.dll迁移中各种问题2
解决:手动标记***************************************************************************************************************************************************************************************************************sharemem。师兄回答:不用一行一行看,只需要了解一下这个功能。
Linux——详解共享内存shared memory
共享内存本质上就是内存中的一块区域,用于进程间通信使用。该内存空间由操作系统分配与管理。与文件系统类似的是,操作系统在管理共享内存时,不仅仅有内存数据块,同时还会创建相应结构体来记录该共享内存属性,以便于管理。因此,共享内存不只有一份,可以根据需求申请多个。进程之间进行通信的时候,会获取 到共享内存的地址,写端进程写入数据,读端进程通过直接访问内存完成数据读取。
共享内存使用的基本思路和接口
共享内存的基本使用方法和接口介绍
【Linux】学习记录_13_共享内存
共享的内存需要进程自己去维护好,如同步、互斥等工作,共享内存是属于临界资源,在某一时刻最多只能有一个进程对其操作(读/写数据), 共享内存一般不能单独使用,而要配合信号量、互斥锁等协调机制,让各个进程在高效交换数据的同时, 不会发生数据践踏、破坏等意外。虽然shmdt()函数很简单,但是还是有注意要点的:该函数并不删除所指定的共享内存区, 而只是将先前用shmat()函数映射好的共享内存脱离当前进程,共享内存还是存在于物理内存中。shmat()函数调用成功后返回共享内存的起始地址。
186



被折叠的 条评论
为什么被折叠?



