我们普通的像PIPE,FIFO,消息队列等的通信方式如下图:
这种方式的通信不论读写,都需要内核态(系统调用 read,write,pipe,mkfifo,msgget,msgsnd,msgrcv等)的介入,而且都需要经过数据从虚拟地址空间到物理地址空间的拷贝。
而共享内存的通信方式则都避免了以上的通信问题,直接为两个进程开辟相同的内存空间进行数据交互。
获取共享内存的对象ID ,创建或打开一个共享内存对象
a. 头文件
b. int shmget (key_t key, size_t size, int shmflg);
c. 函数参数
key
IPC对象的键值,一般为IPC_PRIVATE 或者ftok返回的key值size
共享内存的大小,一般为物理内存页(4K)的整数倍shmflg
:d. 返回值:共享内存的标识ID
映射共享内存:
a. 头文件
b. void *shmat(int shmid,const void *shmaddr,int shmflg);
c. 功能:将shmid标识的共享内存引入到当前进程的虚拟地址空间
d. 函数参数:
shmid
共享内存的IPC对象IDshmaddr
shmflg
e. 返回值:共享内存段的地址
解除共享内存映射
a. 头文件
b. int shmdt(const void * shmaddr);
c. 功能:解除内粗映射,将共享内存分离出当前进程的地址空间
d. 函数参数:
shmaddr
共享内存地址e. TIPS:
shmdt
仅仅是使进程和共享内存脱离关系,将共享内存的引用计数是减1shmctl
的IPC_RMID命令才会删除共享内存设置共享内存属性
a. 头文件
b. int shmctl(int shmid,int cmd,struct shmid_ds *buf);
c. 函数功能:获取/设置共享内存对象属性
d. 函数参数
- shmid
共享内存对象的ID
- cmd
:
IPC_RMID :删除共享内存及关联的shmid_ds数据结构
IPC_STAT: 将该共享内存关联的shmid_ds数据结构拷贝到参数buf中
IPC_SET: 使用buf中的数据更新与该共享内存对象相关联的shmid_ds
IPC_INFO:获取系统共享内存相关的信息
IPC_LOCK: 将一个共享内存段锁进内存,防止被swap出去
IPC_UNLOCK: 将一个共享内存解锁
shmid_ds *buf
数据结构如下
struct shmid_ds { struct ipc_perm shm_perm; /* operation permissions */int shm_segsz; /* size of segment in bytes */pid_t shm_lpid; /* pid of last shm op */pid_t shm_cpid; /* pid of creator */short shm_nattch; /* # of current attaches */time_t shm_atime; /* last shmat() time*/time_t shm_dtime; /* last shmdt() time */time_t shm_ctime; /* last change by shmctl() */void *shm_internal; /* sysv stupidity */};
写端shm_write.c
:
#include
#include
#include
#include
#include
#include
#include int main()
{ //key_t key = ftok("./",111);key_t key = 12345;//根据key值生成共享内存对象的唯一标识int shm_id = shmget(key,4096,IPC_CREAT|0666);//将当前进程加入共享内存,这里设置共享内存地址为NULL时//系统会自动为当前进程分配一个合适的内存空间,并返回共享内存的地址char *shm_p = shmat(shm_id , NULL, 0);memset (shm_p,0,4096);//从标准输入获取内容到共享内存的地址fgets(shm_p,4096,stdin);//等待输入完成,删除共享内存sleep(10);//当前进程创建的共享内存引用计数为0的时候,删除共享内存shmctl(shm_id,IPC_RMID,NULL);return 0;
}
读端shm_read.c
#include
#include
#include
#include
#include
#include
#include int main() {
// key_t key = ftok("./",111);key_t key = 12345;int shm_id = shmget(key, 4096, 0666);//和写端访问到了相同的共享内存区域,并获取内容存放到指针变量char *shm_p = shmat(shm_id , NULL, 0);printf("From SHM: %s
",shm_p);//删除当前进程与共享内存的映射关系,同时共享内存的引用计数减一shmdt(shm_p);return 0;
}
通过命令ipcs -m
可以查看系统共享内存
需要先执行写入,再去运行读端读出;以上输出如下:
更多内容,欢迎关注微信公众号:全菜工程师小辉~前言在笔者上一篇博客,详解了NIO,并总结NIO相比BIO的效率要高的三个原因,彻底搞懂NIO效率高的原理。这篇博客将针对第三个原因,进行更详细的讲解。首先澄清,零拷贝与内存直接映射并不是Java中独有的概念,并且这两个技术并不是等价的。零拷贝零拷贝是指避免在用户态(User-space)...
一、预备知识—程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈,如果还不清楚,那么就把它想成数组,它的内存分配是连续分配的,即,所分配的内存是在一块连续的内存区域内.当我们声明变量时,那么编译器...
我的爱机是一台ThinkPad T420,原装三星DDR 1333 4G内存一根,还剩一根内存位置,最近趁京东6.18促销,准备增加一根物理内存。为了确保兼容性,觉得仍然选购DDR 1333 4G内存,于是购买了金士顿这款,比如DDR3 1600的还贵。 这个安装过程完全参照该内存的网页提示进行 这里简单记录一下,以备...
陪伴我多年的老本ThinkPad T420渐渐垂垂老矣, 我想更新一下可以更新的部分, 比如将2.5寸HDD更换为SSD, 将单条4G内存再增加一根, 凡此种种想法, 可能最后归结为如何获取该笔记本的硬件配置信息, 在windows下面使用鲁大师之类的检测软件, 也许很好搞定,但是在Ubuntu 14.04平台上如果办到呢? 很简单...
一.内存错误出现的场景 这几天在重构ATS插件代码的过程中遇到了烦人的内存泄露问题, 周五周六连续两天通过走查代码的方法,未能看出明显的导致内存错误的代码, 同时也觉得C和C++混合编程得到一个动态库, 在一个.cpp主文件中,即用new又用malloc来动态分配内存, 可能会导致内存错误.后来网上调研和查资料发现, new和mal...
一、首先是安装VMWare tools 安装过程可参考:http://www.cnblogs.com/jiu0821/p/7559949.html 二、解决安装VMWare tools后/mnt中有hgfs但没共享文件 前提:在虚拟机软件中设置了共享目录 此时在linux中进入 /mnt/hgfs 文件夹,但发现共享的文件没...
Windows 2000/XP/2003版本的操作系统提供了默认共享功能,这些默认的共享都有“$”标志,意为隐含的,包括所有的逻辑盘(C$,D$,E$……)和系统目录Winnt或Windows(admin$)。 带来的问题 微软的初衷是便于网管进行远程管理,这虽然方便了局域网用户,但对我们个人用户来说这样的设置是不安全的。...
文章目录思维导图通信原理优势POSIX 共享内存 编程接口编程案例 思维导图 之前学习过sysemV 的共享内存的实现及使用原理,参考linux进程间通信:system V 共享内存 POSIX 同样提供共享内存的接口,基本原理和system V的共享内存是一样的。 通信原理 多个进程共享物理内存的同一块区域(通常称之...