阐述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 能够使用自己的信号量来实现,具体细节将在后面同步相关专栏具体解说。
本节源代码下载:

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/419680.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php io select,Python IO多路复用之——select方案服务端和客户端代码【python源码详解】...

准备文件&#xff1a;IO.py 服务端代码tcp_c.py 客户端代码IO.py 代码&#xff1a;from select import * #引入 select 模块from socket import * #引入 socket 模块s socket() #实例化一个socket 对象s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #设置端口可重用s.bind((0.0.0…

NDK和项目依赖

NDK使用 JDK:Java Development KitSDK:Software Development KitNDK:Native Development KitJNI: Java Nattive InterfaceNDK开发流程&#xff1a; 下载NDK并配置NDK路径新建项目 修改build.gradle文件 替换classpath:com.android.tools.build:gradle-experimental:0.4.0 替换a…

java创建树形子目录,Java之File类及递归树形展示目录_20150804

Java之File类及递归树形展示目录20150804下面的构造函数可以用来生成File 对象&#xff1a;File(String directoryPath)File(String directoryPath, String filename)File(File dirObj, String filename)这里&#xff0c;directoryPath是文件的路径名&#xff0c;filename 是文…

使用PDFBox解析PDF文件

今天在Nutch源码中准备增加一个PDF处理方面的功能&#xff0c;其中要做的一步是提取出PDF文档中的文本信息。考虑了一下&#xff0c;还是准备使用PDFBox。看了一下&#xff0c;Nutch源码中的parse-tika插件下有一个PDFBox&#xff0c;不过是1.1.0版本&#xff0c;很多PDF文档都…

matlab 数字图像滤波,数字图像处理 (基于Matlab) 滤波

《数字图像处理》实验报告一、实验目的(不少于200字)一、第一个实验用的是各种空间域的方式来滤波&#xff0c;也就是直接把图像和空间滤波器的模板做卷积&#xff0c;当然图像处理很重要的一个部分还有频域的处理。这就涉及到图像的傅里叶变换&#xff0c;通过将空域内的图像傅…

myelicpes怎么导入PHP项目,利用PHP执行SQL文件,将SQL文件导入到数据库

引用如何利用php自动执行 sql文件。其实很简单&#xff0c;就是获取sql文件中的内容&#xff0c;然后将每一句sql语句一次执行就行啦。//读取文件内容$_sql file_get_contents(test.sql);$_arr explode(;, $_sql);$_mysqli new mysqli(DB_HOST,DB_USER,DB_PASS);if (mysqli_…

atitit. 分销系统规划p8k

atitit. 分销系统规划p8k 1. 商户平台管理 overview2 1.1. 分销业务管理2 1.2. 文案管理2 1.3. 订单管理3 1.4. 统计报表3 1.5. 财务结算3 1.6. 自身信息管理4 2. 商户后台详细5 3. 推广人后台6 3.1. 产品及文案6 3.2. 订单与结算6 3.3. 下线邀请与奖励6 3.4. 订单统计6 3.5. 资…

php数据访问层设计,php - Zend框架数据访问层(DAL) - 堆栈内存溢出

好吧&#xff0c;在处理Data Access Layer &#xff0c;您必须考虑的第一件事是该层还具有子层 &#xff0c;在现代框架中很难找到名为“ dal”的文件夹(我以Zend为基础框架和Symfony)。其次&#xff0c;关于ActiveRecord &#xff0c;您必须知道默认情况下Zend Frameworks 不会…

matlab 8.4,《DSP using MATLAB》Problem 8.42

代码&#xff1a;%% ------------------------------------------------------------------------%% Output Info about this m-filefprintf(‘\n***********************************************************\n‘);fprintf(‘ Problem 8.42 \n\n‘);banner();%% ------------…

lua的string.gsub初使用

今天在学习lua&#xff0c;熟悉项目代码的过程中&#xff0c;发现string.gsub好高级&#xff0c;所以在此mark下。 以下是lua5.1的官方文档介绍。 string.gsub (s, pattern, repl [, n])Returns a copy of s in which all occurrences of the pattern have been replaced by a …

php对象比较大小,PHP 面向对象:对象的比较

简明现代魔法 -> PHP服务器脚本 -> PHP 面向对象&#xff1a;对象的比较PHP 面向对象&#xff1a;对象的比较2010-04-07在PHP中有 赋值符号、 等于符号 和 全等于符号, 这些符号代表什么意思&#xff1f;当使用比较操作符()时&#xff0c;对象以一种很简单的规则比较&a…

mysql 备份

方法一&#xff1a; 1&#xff0c;暂停Mysql进程或服务 2&#xff0c;复制mysql\data文件夹 3&#xff0c;重新安装程序和mysql, 把 ibdata1及数据库文件夹copy到新目录 4&#xff0c;重启服务 方法二 数据导出&#xff1a;mysqldump -u数据库用户名 -p 要导出的数据库> otc…

php程序变量,PHP 变量

PHP 变量变量是用于存储信息的"容器"&#xff1a;实例$x5;$y6;$z$x$y;echo $z;?>运行实例 与代数类似x5y6zxy在代数中&#xff0c;我们使用字母(如 x)&#xff0c;并给它赋值(如 5)。从上面的表达式 zxy &#xff0c;我们可以计算出 z 的值为 11。在 PHP 中&…

为什么构造函数不能是虚函数

为什么构造函数不能是虚函数 从存储空间角度看&#xff0c;使用虚函数时&#xff0c;系统要有一定的空间开销&#xff0c;当一个类带有虚函数时&#xff0c;编译系统会为该类构造一个虚函数表&#xff08;virtual function table&#xff09;&#xff0c;他是一个指针数组&…

漏洞:WebRTC 泄漏用户IP

WebRTC又称为“网页即时通信”&#xff0c;是一组API函数&#xff0c;它经过W3C组织的认证&#xff0c;支持浏览器之间的语音通话、视频聊天和P2P模式分享文件。 这个协议主要包括&#xff1a;getUserMedia&#xff0c;RTCPeerConnection&#xff0c;RTCDataChannels&…

怎么在电脑安装php文件夹在哪个文件夹,php进行文件上传时找不到临时文件夹怎么办,电脑自动保存的文件在哪里...

php进行文件上传时找不到临时文件夹怎么办PHP上传文件时找不到临时文件夹怎么办&#xff0c;php上传文件时找不到临时文件夹的解决方案&#xff1a;先打开php.ini配置文件&#xff1b;然后修改内容[upload _ tmp _ dir’ c :/windows/temp ‘]&#xff0c;文件夹路径要根据自己…