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--231--2的幂函

    问题描述: 给定一个整数,编写一个函数来判断它是否是 2 的幂次方. 示例 1: 输入: 1 输出: true 解释: 2 0  = 1 示例 2: 输入: 16 输出: true 解释: 2 4   ...

  2. Confluence 6 给一个从 Jira Service Desk 的非许可证用户访问权限

    如果你正在使用 Confluence 为 Jira 服务桌面(Jira Service Desk)的知识库,你可以选择允许所有活动的用户和客户(客户是可以登录的用户,但是这些用户是没有 Conflue ...

  3. mysql之filesort原理

    在执行计划中,可能经常看到有Extra列有filesort,这就是使用了文件排序,这当然是不好的,应该优化,但是,了解一下他排序的原理也许很有帮助,下面看一下filesort的过程: 1.根据表的索引 ...

  4. Single Number II leetcode java

    问题描述: Given an array of integers, every element appears three times except for one. Find that single ...

  5. mybatis批量插入的方式

    批量插入数据经常是把一个集合的数据一次性插入数据库,只需要执行一次sql语句,但是批量插入通常会报框架版本号的错误,本人就遇到 com.alipay.zdal.parser.exceptions.a: ...

  6. vue开发移动端项目 过渡动画问题

     App.vue:  <div id="app"> <div class="content"> <transition :name ...

  7. centos命令行系列之升级glibc到

    1.从http://ftp.gnu.org/gnu/glibc/glibc-2.17.tar.gz 下载文件 2.安装部署 [root@kafzook1 /]# tar -xf glibc-2.17. ...

  8. 前端web的图标的样式

  9. Farm Irrigation(非常有意思的并查集)

    Farm Irrigation Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Tot ...

  10. JAVA的SPI简单应用

    最近在研究dubbo时,发现了JAVA的SPI特性.SPI的全名为Service Provider Interface,是JDK内置的一种服务发现机制. 具体实现: 1.定义一个接口 public i ...