阐述linux IPC(五岁以下儿童):system V共享内存
system V共享内存和posix共享内存类似,system V共享内存是调用shmget函数和shamat函数。
shmget函数创建共享内存区,或者訪问一个存在的内存区,类似系统调用共享内存的open和posix共享内存shm_open函数。
shmget函数原型为:
#include <sys/ipc.h>#include <sys/shm.h>int shmget(key_t key, size_t size, int shmflg);
key: 函数ftok返回值。或者IPC_PRIVATE ,当使用IPC_PRIVATE时。最好两个进程空间是共享的,比方父子进程,否则当前进程产生的共享内存标识(返回值)。在还有一个进程里面不易得到。
ftok函数原型为:key_t ftok(const char *pathname, int proj_id); 參数pathname为文件绝对路径名,proj_id为一个整型标识符。该函数将一个已存在的的路径名和一个整型标识符转化成一个key_t值(返回值),称为IPC键。
size:创建新的共享内存大小,当创建一片新的共享内存时。该值为不为0的參数。假设是读取一片共享内存,该值能够为0。
shmflg:读写权限值组合。
IPC_CREAT(创建新的共享内存)或IPC_CREAT|IPC_EXCL(当将要创建的共享内存已经存在时,再试图创建将返回EEXIST)。
事实上IPC_CREAT和IPC_EXCL的组合和open函数的O_CREAT和O_EXCL组合类似。
函数返回共享内存区的标识。
shmxxx函数操作共享内存将使用该函数返回值。
该函数类似posix共享内存shm_open函数功能。
当shmget创建或打开一个共享内存区后。须要使用函数shmat来将该片共享内存连接到当前进程空间中来,当某一进程使用完共享内存后,使用函数shmdt断开和共享内存的链接。
#include <sys/types.h>#include <sys/shm.h>void *shmat(int shmid, const void *shmaddr, int shmflg);int shmdt(const void *shmaddr);
shmid:是函数shmget函数返回的共享内存标识符。
shmaddr: 连接到调用进程地址空间的地址,假设该參数为NULL,系统选择一个合适地址。假设shmaddr非空而且shmflg指定了选项SHM_RND,那么对应的共享内存链接到由shmaddr參数指定的地址向下舍入一个SHMLAB常值。假设shmaddr非空而且shmflg未指定SHM_RND,共享内存地址链接到shmaddr參数指定的地址。
shmflg:能够指定SHM_RND和SHM_RDONLY(仅仅读),假设指定SHM_RDONLY选项。那么调用进程对该片共享内存仅仅有读权限,否则,进程对该片内存将有读写权限。
函数shmdt不会删除指定的共享内存,它仅仅是断开和该片共享内存的链接而已。当一个进程终止后。该进程链接的共享内存将自己主动断开。
shmat函数成功返回当前进程共享内存地址,失败返回(void *)-1;shmdt成功返回0。失败返回-1;
删除共享内存须要函数shmctl调用IPC_RMID命令来完毕。
#include <sys/ipc.h>#include <sys/shm.h>int shmctl(int shmid, int cmd, struct shmid_ds *buf);
shmid:共享内存区标识。
cmd:对共享内存的操作命令,命令IPC_RMID销毁(destroy)一片共享内存,销毁之后全部shmat。shmdt,shmctl对该片内存操作都将失效。销毁该共享内存要等到该共享内存引用计数变为0才进行。IPC_SET命令设置shmid_ds结构成员;IPC_STAT返回当前共享内存结构。其余命令查看man手冊。
buf:为指向shmid_ds数据结构;
system V 共享内存演示样例:
server process:
int sln_shm_get(char *shm_file, void **mem, int mem_len)
{int shmid;key_t key;if (NULL == fopen(shm_file, "w+")) {printf("fopen: %s\n", strerror(errno));return -1;}key = ftok(shm_file, 0);if (key < 0) {printf("ftok: %s\n", strerror(errno));return -1;}shmid = shmget(key, mem_len, IPC_CREAT);if (shmid < 0) {printf("shmget: %s\n", strerror(errno));return -1;}*mem = (void *)shmat(shmid, NULL, 0);if ((void *)-1 == *mem) {printf("shmat: %s\n", strerror(errno));return -1;}return shmid;
}int main(int argc, const char *argv[])
{char *shm_file = NULL;char *shm_buf = NULL;int shmid;shmid = sln_shm_get(SHM_IPC_FILENAME, (void **)&shm_buf, SHM_IPC_MAX_LEN);if (shmid < 0) {return -1;}snprintf(shm_buf, SHM_IPC_MAX_LEN, "Hello system V shaare memory IPC! this is write by server.");sleep(15); printf("System V server delete share memory segment!\n");//shmdt(shm_buf);shmctl(shmid, IPC_RMID, NULL); //server在15秒之后destroy该片共享内存。此时客户进程将获取不到共享内存的内容return 0;
}
client process:
int sln_shm_get(char *shm_file, void **mem, int mem_len)
{int shmid;key_t key;key = ftok(shm_file, 0);if (key < 0) {printf("ftok: %s\n", strerror(errno));return -1;}shmid = shmget(key, mem_len, IPC_CREAT);if (shmid < 0) {printf("shmget: %s\n", strerror(errno));return -1;}*mem = (void *)shmat(shmid, NULL, 0);if ((void *)-1 == *mem) {printf("shmat: %s\n", strerror(errno));return -1;}return shmid;
}int main(int argc, const char *argv[])
{char *shm_buf = NULL;int i;if (sln_shm_get(SHM_IPC_FILENAME, (void **)&shm_buf, SHM_IPC_MAX_LEN) < 0) {return -1;}printf("ipc client get: %s\n", shm_buf);return 0;
}
执行时,首先执行server process,使用命令ipcs能够查看当前系统共享内存:
# ipcs
------ Message Queues --------
key msqid owner perms used-bytes messages ------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x0010a797 131072 root 0 4096 1 ------ Semaphore Arrays --------
key semid owner perms nsems
能够看到存在一个共享内存区,当中key为:0x0010a797 ,共享内存ID为:131072
# ./client
ipc client get: Hello system V shaare memory IPC! this is write by server.
#
当server进程destroy共享内存之后,再反复上面步骤,
# ipcs ------ Message Queues --------
key msqid owner perms used-bytes messages ------ Shared Memory Segments --------
key shmid owner perms bytes nattch status ------ Semaphore Arrays --------
key semid owner perms nsems 此时共享内存已经不在了,但文件依旧存在。
# ./client ipc client get: #
此时client已经不能获取之前共享内存内容了。
另外,ipcrm命令能够在命令行上删除指定共享内存区。
通过读取文件/proc/sys/kernel/shmmax能够获取系统所支持共享内存最大值,
# cat /proc/sys/kernel/shmmax
33554432
#
能够看到我眼下系统支持最大个共享内存值为:32M。
通过上演示样例能够看到system V共享内存和posix共享内存类似,只是posix共享内存的大小能够随时通过ftruncate改变,而system V 的共享内存大小在shmget时就已经确定下来了。
相同的,system V共享内存大多数时候也须要在多进程之间同步,system V 能够使用自己的信号量来实现,具体细节将在后面同步相关专栏具体解说。
本节源代码下载:
版权声明:本文博客原创文章,博客,未经同意,不得转载。
转载于:https://www.cnblogs.com/mengfanrong/p/4712512.html
阐述linux IPC(五岁以下儿童):system V共享内存相关推荐
- Linux IPC实践(9) --System V共享内存
共享内存API #include <sys/ipc.h> #include <sys/shm.h>int shmget(key_t key, size_t size, int ...
- Linux进程间通信一 System V 共享内存简介与示例
目录 1. System V共享内存简介 2. API介绍 2.0 key_t和标识符 2.1 创建system v共享内存 2.2 映射共享内存并使用 2.3 取消共享内存映射 2.4 控制共享内 ...
- 嵌入式Linux系统编程学习之二十三 System V 共享内存机制
文章目录 前言 一.ftok 函数 二.shmget 函数 三.shmat 函数 四.shmdt 函数 五.shmctl 函数 补充 前言 共享内存也是进程间(进程间不需要有继承关系)通信的一种常 ...
- 【Linux】进程间通信 - 匿名/命名管道与System V共享内存
目录 前言 一.管道 0.什么是管道 1).管道的概念 2).管道的本质 3).管道指令: "|" 1.匿名管道 1).如何创建匿名管道 2).如何使用匿名管道进行通信 3).匿名 ...
- 【Linux篇】第十二篇——进程间通信(管道+system V共享内存)
进程间通信介绍 概念 目的 本质 分类 管道 什么是管道 匿名管道 匿名管道的原理 pipe函数 匿名管道使用步骤 管道读写规则 管道的特点 管道的大小 命名管道 命名管道的原理 使用命令创建命名管道 ...
- linux环型共享内存,Linux system v 共享内存
system v 共享内存 #include #include int shmget(key_t key, size_t size, int shmflg); 建立:进程与共享内存的关联关系 key_ ...
- mmap内存映射、system V共享内存和Posix共享内存
linux内核支持多种共享内存方式,如mmap内存映射,Posix共享内存,以system V共享内存.当内核空间和用户空间存在大量数据交互时,共享内存映射就成了这种情况下的不二选择.它能够最大限度的 ...
- 共享内存之——system V共享内存
System V 的IPC对象有共享内存.消息队列.信号灯(量). 注意:在IPC的通信模式下,不管是共享内存.消息队列还是信号灯,每个IPC的对象都有唯一的名字,称为"键(key)&quo ...
- 【校招 --阶段一 系统编程】system V共享内存
一.什么是system V共享内存 共享内存区是最快的IPC形式.一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到 内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此 ...
最新文章
- 如何查看linux 操作系统信息
- .netcore多语言解决方案
- C#如何获得当前程序所在的目录
- 海外净利润低?海尔智家H股上市有望看齐国内!
- Java黑皮书课后题第7章:**7.34(对字符串中的字符排序)使用以下方法头编写一个方法,返回一个排序好的字符串。编写一个测试程序,提示用户输入一个字符串,显示排序好的字符串
- Leetcode:892. 三维形体的表面积(Java)
- 【转】PHP远程调试之XDEBUG
- 【bzoj1194】 HNOI2006—潘多拉的盒子
- 使用s:property value=4/是报错
- 7 php程序的调试方法_PHP 程序员的调试技术
- Java编程思想阅读收获
- 苹果自带输入法怎么换行_小屏幕手机的福音:分享自用输入法皮肤丨免费
- 【修正版】狼叔的2017年总结:
- access是用来干什么的_access数据库都能干什么
- Unity 车辆跟随路径点缓动移动
- 关于hive报错expression not in group by key ‘.....‘
- 12 Best Custom ROMs for Android You Can Install
- 洛谷P2306 被yyh虐的mzc
- CSU 1725 加尔鲁什·地狱咆哮对阵虚灵大盗拉法姆
- 解读:机器学习预测收益模型应该采取哪种度量指标
热门文章
- C/C++中预编译#,##,#error作用
- Linux tty驱动程序一 架构
- [react] react是什么?它的主要特点是什么?
- [react] 在React中你有遇到过安全问题吗?怎么解决?
- Taro+react开发(95):问答模块02
- 前端学习(3219):对props进行限制
- [html] 怎样去除iOS和Android中的输入URL地址的控件条呢?
- [html] 什么是空元素?常用的空元素有哪些?
- PS教程第二十四课:魔法棒
- 前端学习(1686):前端系列javascript基础面试总结