【版权声明:尊重原创。转载请保留源: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 能够使用自己的信号量来实现,具体细节将在后面同步相关专栏具体解说。
本节源代码下载:

http://download.csdn.net/detail/gentleliu/8140887

版权声明:本文博客原创文章,博客,未经同意,不得转载。

转载于:https://www.cnblogs.com/mengfanrong/p/4712512.html

阐述linux IPC(五岁以下儿童):system V共享内存相关推荐

  1. Linux IPC实践(9) --System V共享内存

    共享内存API #include <sys/ipc.h> #include <sys/shm.h>int shmget(key_t key, size_t size, int ...

  2. Linux进程间通信一 System V 共享内存简介与示例

    目录 1. System V共享内存简介 2. API介绍 2.0 key_t和标识符 2.1  创建system v共享内存 2.2 映射共享内存并使用 2.3 取消共享内存映射 2.4 控制共享内 ...

  3. 嵌入式Linux系统编程学习之二十三 System V 共享内存机制

    文章目录 前言 一.ftok 函数 二.shmget 函数 三.shmat 函数 四.shmdt 函数 五.shmctl 函数 补充 前言   共享内存也是进程间(进程间不需要有继承关系)通信的一种常 ...

  4. 【Linux】进程间通信 - 匿名/命名管道与System V共享内存

    目录 前言 一.管道 0.什么是管道 1).管道的概念 2).管道的本质 3).管道指令: "|" 1.匿名管道 1).如何创建匿名管道 2).如何使用匿名管道进行通信 3).匿名 ...

  5. 【Linux篇】第十二篇——进程间通信(管道+system V共享内存)

    进程间通信介绍 概念 目的 本质 分类 管道 什么是管道 匿名管道 匿名管道的原理 pipe函数 匿名管道使用步骤 管道读写规则 管道的特点 管道的大小 命名管道 命名管道的原理 使用命令创建命名管道 ...

  6. linux环型共享内存,Linux system v 共享内存

    system v 共享内存 #include #include int shmget(key_t key, size_t size, int shmflg); 建立:进程与共享内存的关联关系 key_ ...

  7. mmap内存映射、system V共享内存和Posix共享内存

    linux内核支持多种共享内存方式,如mmap内存映射,Posix共享内存,以system V共享内存.当内核空间和用户空间存在大量数据交互时,共享内存映射就成了这种情况下的不二选择.它能够最大限度的 ...

  8. 共享内存之——system V共享内存

    System V 的IPC对象有共享内存.消息队列.信号灯(量). 注意:在IPC的通信模式下,不管是共享内存.消息队列还是信号灯,每个IPC的对象都有唯一的名字,称为"键(key)&quo ...

  9. 【校招 --阶段一 系统编程】system V共享内存

    一.什么是system V共享内存 共享内存区是最快的IPC形式.一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到 内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此 ...

最新文章

  1. 如何查看linux 操作系统信息
  2. .netcore多语言解决方案
  3. C#如何获得当前程序所在的目录
  4. 海外净利润低?海尔智家H股上市有望看齐国内!
  5. Java黑皮书课后题第7章:**7.34(对字符串中的字符排序)使用以下方法头编写一个方法,返回一个排序好的字符串。编写一个测试程序,提示用户输入一个字符串,显示排序好的字符串
  6. Leetcode:892. 三维形体的表面积(Java)
  7. 【转】PHP远程调试之XDEBUG
  8. 【bzoj1194】 HNOI2006—潘多拉的盒子
  9. 使用s:property value=4/是报错
  10. 7 php程序的调试方法_PHP 程序员的调试技术
  11. Java编程思想阅读收获
  12. 苹果自带输入法怎么换行_小屏幕手机的福音:分享自用输入法皮肤丨免费
  13. 【修正版】狼叔的2017年总结:
  14. access是用来干什么的_access数据库都能干什么
  15. Unity 车辆跟随路径点缓动移动
  16. 关于hive报错expression not in group by key ‘.....‘
  17. 12 Best Custom ROMs for Android You Can Install
  18. 洛谷P2306 被yyh虐的mzc
  19. CSU 1725 加尔鲁什·地狱咆哮对阵虚灵大盗拉法姆
  20. 解读:机器学习预测收益模型应该采取哪种度量指标

热门文章

  1. C/C++中预编译#,##,#error作用
  2. Linux tty驱动程序一 架构
  3. [react] react是什么?它的主要特点是什么?
  4. [react] 在React中你有遇到过安全问题吗?怎么解决?
  5. Taro+react开发(95):问答模块02
  6. 前端学习(3219):对props进行限制
  7. [html] 怎样去除iOS和Android中的输入URL地址的控件条呢?
  8. [html] 什么是空元素?常用的空元素有哪些?
  9. PS教程第二十四课:魔法棒
  10. 前端学习(1686):前端系列javascript基础面试总结