system的共享内存指的是内核指定一块内存区域映射到虚拟地址空间供进程通信使用的机制

1\创建或打开共享内存块
函数原型
int shmget(key_t key, size_t size, int shmflg)

参数
参数1:一个key_t类型的变量.IPC_PRIVATE或者>0的值
参数2:要创建共享内存的大小,取值为页面大小的整数倍
参数3:取IPC_CREAT或者IPC_EXCL

返回值
返回一个共享内存块的标识符

2\使用共享内存块
函数原型
void *shmat(int shmid, const void *shmaddr, int shmflg)

参数
参数1:shmget返回的共享内存块标识符
参数2:指定共享内存的虚拟地址位置,可取NULL,表示由内核管理
参数3:SHM_RND

返回值
返回进程虚拟地址空间内的一个地址,失败-1

实验代码

/* 向共享内存地址空间写入数据shm_write.c */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <errno.h> #define KEY_NAME "/tmp/mkfifo.0001" int main(int argc, char *argv[])
{
int myshmid;
void *shmaddr; /* 创建成功的虚拟内存地址 */
key_t key = ftok(KEY_NAME, 0x1235); /* 创建一个key */
if(key == -1)
{
printf("ftok key failed, app exit! error : %s\n", strerror(errno));
exit(-1);
}
printf("ftok succeed, key : %d\n", key); myshmid = shmget(key, 1024, IPC_CREAT|IPC_EXCL|0666); /* 创建共享内存 */
if(myshmid == -1)
{
printf("shmget failed, app exit! error : %s\n", strerror(errno));
exit(-1);
}
printf("shmget succeed, shmid : %d\n", myshmid); shmaddr = shmat(myshmid, NULL, SHM_RND); /* 由内核指定一块地址空间 */
if(shmaddr == (void *)-1)
{
printf("shmat failed, app exit! error : %s\n", strerror(errno));
exit(-1);
}
printf("shmat succeed, share memory address : 0x%x\n", shmaddr); char shmdata[50] = "This is a SYSTEM V share memory test!";
strncpy(shmaddr, shmdata, sizeof(shmdata));
printf("write data into address : 0x%x succeed!\n", shmaddr); return 0;
}
/* 向共享内存地址空间读取数据shm_read.c */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <errno.h> #define KEY_NAME "/tmp/mkfifo.0001" int main(int argc, char *argv[])
{
int myshmid;
key_t key = ftok(KEY_NAME, 0x1235); /* 创建一个key */
if(key == -1)
{
printf("ftok key failed, app exit! error : %s\n", strerror(errno));
exit(-1);
}
printf("ftok succeed, key : %d\n", key); myshmid = shmget(key, 1024, IPC_EXCL|0666); /* 获取shmid */
if(myshmid == -1)
{
printf("get shmid failed, app exit! error : %s\n", strerror(errno));
exit(-1);
}
printf("shmget succeed, shmid : %d\n", myshmid); void *rdaddr = shmat(myshmid, NULL, 0);
printf("read data from shmid : %d, data : %s\n", myshmid, rdaddr); shmdt(shmaddr); /* 将共享内存的虚拟地址空间与进程空间进行分离 */
printf("shdt succeed!\n"); int result = shmctl(myshmid, IPC_RMID, (struct shmid_ds *)NULL); /* 删除共享内存 */
if(result == -1)
{
printf("delete share memory failed, app exit. error : %s!\n", strerror(errno));
exit(-1);
}
printf("delete share memory succeed!\n");
return 0;
}

实验结果

运行之前系统的共享内存使用情况

创建共享内存并写入数据

读取数据并删除共享内存

ps:创建共享内存的系统限制
SHMMNI:系统所能够创建共享内存的最大个数 cat /proc/sys/kernel/shmmni
SHMMIN:一个共享内存段的最小字节数
SHMMAX:一个共享内存段的最大字节数 cat /proc/sys/kernel/shmmax
SHMALL:系统中共享内存的分页总数 cat /proc/sys/kernel/shmall
SHMSEG:一个进程允许attach的共享内存段的最大个数

system的共享内存实例的更多相关文章

  1. C#共享内存实例 附源码

    原文 C#共享内存实例 附源码 网上有C#共享内存类,不过功能太简单了,并且写内存每次都从开头写.故对此进行了改进,并做了个小例子,供需要的人参考. 主要改进点: 通过利用共享内存的一部分空间(以下称 ...

  2. System V共享内存介绍

    (一)简单概念 共享内存作为一种进程间通信的方式,其相较于其他进程间通信方式而言最大的优点就是数据传输速率快.其内部实现的方式采用了Linux进程地址空间中的mmap文件映射区,将文件内容直接映射到各 ...

  3. Linux进程通信之System V共享内存

    前面已经介绍过了POSIX共享内存区,System V共享内存区在概念上类似POSIX共享内存区,POSIX共享内存区的使用是调用shm_open创建共享内存区后调用mmap进行内存区的映射,而Sys ...

  4. 阐述linux IPC(五岁以下儿童):system V共享内存

    [版权声明:尊重原创.转载请保留源:blog.csdn.net/shallnet 要么 .../gentleliu,文章学习交流,不用于商业用途]         system V共享内存和posix ...

  5. UNIX环境高级编程——System V 共享内存区

    共享内存区域是被多个进程共享的一部分物理内存.如果多个进程都把该内存区域映射到自己的虚拟地址空间,则这些进程就都可以直接访问该共享内存区域,从而可以通过该区域进行通信.共享内存是进程间共享数据的一种最 ...

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

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

  7. php进程(线程)通信基础--System V共享内存

    PHP默认情况没有开启功能,要支持该功能在编译PHP的时候要加入下面几个选项  System V消息,--enable-sysvmsg   System V信号量支持,--enable-sysvsem ...

  8. System V 共享内存区

    1.概述 系统调用mmap通过映射一个普通文件实现共享内存.System V 则是通过映射特殊文件系统shm中的文件实现进程间的共享内存通信.也就是说,每个共享内存区域对应特殊文件系统shm中的一个文 ...

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

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

随机推荐

  1. LeetCode--235--二叉树的最近公共祖先

    问题描述: 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结点 x,满足 x 是 p.q 的 ...

  2. Node.js 知识(教程)

    JavaScript on the Server JavaScript was originally built for web browsers, but with Node.js we can u ...

  3. 启动mysql5.7异常The server quit without updating PID file [FAILED]sql/data/***.pi根本解决方案

    异常表现 mysql5.7启动时报错 Starting MySQL...The server quit without updating PID file [FAILED]sql/data/insta ...

  4. spring boot(十五)spring boot+thymeleaf+jpa增删改查示例

    快速上手 配置文件 pom包配置 pom包里面添加jpa和thymeleaf的相关包引用 <dependency> <groupId>org.springframework.b ...

  5. 自定义alert弹框,title不显示域名

    问题: 系统默认的alert弹框的title会默认显示网页域名 解决办法: (修改弹框样式) (function() { window.alert = function(name) { $(" ...

  6. poj 1080 基因组(LCS)

    Human Gene Functions Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 19376   Accepted:  ...

  7. JS保留小数 去尾法 进一法 四舍五入法

    //toFixed 四舍五入遇到坑. 1.235.toFixed(2) = 1.23 1.2350001.toFixed(2) = 1.24 //去尾法 Number.prototype.toFloo ...

  8. Segments

    Segments Given n segments in the two dimensional space, write a program, which determines if there e ...

  9. C++ string::size_type

    从逻辑上讲,size()成员函数应该似乎返回整型数值,但事实上,size操作返回是string::size_type类型的值.string类类型和其他许多库类型都定义了一些配套类型(companion ...

  10. npm使用过程中出现的错误

    1.安装npm install axios -S报错install "npm ERR! Error: EPERM: operation not permitted" error 经 ...