阐述linux IPC(五岁以下儿童):system V共享内存
【版权声明:尊重原创。转载请保留源:blog.csdn.net/shallnet 要么 .../gentleliu,文章学习交流,不用于商业用途】
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 能够使用自己的信号量来实现,具体细节将在后面同步相关专栏具体解说。
本节源代码下载:
版权声明:本文博客原创文章,博客,未经同意,不得转载。
阐述linux IPC(五岁以下儿童):system V共享内存的更多相关文章
- Linux进程通信之System V共享内存
前面已经介绍过了POSIX共享内存区,System V共享内存区在概念上类似POSIX共享内存区,POSIX共享内存区的使用是调用shm_open创建共享内存区后调用mmap进行内存区的映射,而Sys ...
- 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 共享内存
system v 共享内存 #include <sys/types.h> #include <sys/shm.h> int shmget(key_t key, size_t s ...
- linux网络编程之system v共享内存
接着上次的共享内存继续学习,这次主要是学习system v共享内存的使用,下面继续: 跟消息队列一样,共享内存也是有自己的数据结构的,system v共享内存也是随内核持续的,也就是说当最后一个访问内 ...
- System V 共享内存区
1.概述 系统调用mmap通过映射一个普通文件实现共享内存.System V 则是通过映射特殊文件系统shm中的文件实现进程间的共享内存通信.也就是说,每个共享内存区域对应特殊文件系统shm中的一个文 ...
- System V共享内存介绍
(一)简单概念 共享内存作为一种进程间通信的方式,其相较于其他进程间通信方式而言最大的优点就是数据传输速率快.其内部实现的方式采用了Linux进程地址空间中的mmap文件映射区,将文件内容直接映射到各 ...
- UNIX环境高级编程——System V 共享内存区
共享内存区域是被多个进程共享的一部分物理内存.如果多个进程都把该内存区域映射到自己的虚拟地址空间,则这些进程就都可以直接访问该共享内存区域,从而可以通过该区域进行通信.共享内存是进程间共享数据的一种最 ...
- 共享内存之——system V共享内存
System V 的IPC对象有共享内存.消息队列.信号灯(量). 注意:在IPC的通信模式下,不管是共享内存.消息队列还是信号灯,每个IPC的对象都有唯一的名字,称为"键(key)&quo ...
- System V共享内存
目录 1. 概述 2. System V共享内存API shmget shmat shmdt shmctl 3. 简单的程序 代码实现 common.h shmcreate.c shmrmid.c s ...
随机推荐
- 2015西雅图微软总部MVP峰会
2015 西雅图微软总部MVP峰会记录 2015 西雅图微软总部MVP峰会记录 今年决定参加微软MVP全球峰会,在出发之前本人就已经写这篇博客,希望将本次会议原汁原味奉献给大家 因为这次是本人第一 ...
- hdu 3076 ssworld VS DDD (概率dp)
///题意: /// A,B掷骰子,对于每一次点数大者胜,平为和,A先胜了m次A赢,B先胜了n次B赢. ///p1表示a赢,p2表示b赢,p=1-p1-p2表示平局 ///a赢得概率 比一次p1 两次 ...
- 遗传算法解决旅行商问题(TSP)
这次的文章是以一份报告的形式贴上来,代码只是简单实现,难免有漏洞,比如循环输入的控制条件,说是要求输入1,只要输入非0就行.希望会帮到以后的同学(*^-^*) 一.问题描述 旅行商问题(Traveli ...
- SQL Server错误代码及解释(留着备用)
原文:SQL Server错误代码及解释(留着备用) 转自:http://www.ajia.me/Article/193.html Code Error Message 0 操作成功完成. 1 功能 ...
- Event Sourcing
Event Sourcing - ENode(二) 接上篇文章继续 http://www.cnblogs.com/dopeter/p/4899721.html 分布式系统 前篇谈到了我们为何要使用分布 ...
- [ExtJS5学习笔记]第22 Extjs5正在使用beforeLabelTpl添加所需的配置选项标注星号标记
本文地址:http://blog.csdn.net/sushengmiyan/article/details/39395753 官方样例:http://docs.sencha.com/extjs/5. ...
- HTTP 请求报文 响应报文(转)
引言 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议.所有的WWW文件都必须遵守这个标准.设计HTTP最初的目的是为了提供一种发 ...
- Play Framework + ReactiveMongo
Play Framework + ReactiveMongo Play!是一个full-stack(全栈的)Java/Scala Web应用框架,包括一个简单的无状态MVC模型,具有Hibernate ...
- KMP算法(转)
KMP算法 在介绍KMP算法之前,先介绍一下BF算法. 一.BF算法 BF算法是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串P的第一个字符进行匹配,若相等,则继续比较S的第二个 ...
- jquery初步总结
1.$(document).ready()方法和window.onload差分法 为页元件的正确操作,我们需要把操作元件JS编写的代码$(document).ready()(Jquery)或windo ...