linux共享内存简单介绍以及编码演示
共享内存的基本概念
共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。
下图是共享内存示意图:

下图是用管道或者消息队列传递数据示意图:
内核为每个IPC对象维护一个数据结构

下图是用共享内存传递数据示意图:

System V共享内存API:
首先了解一下下面结构体
struct shmid_ds {
struct ipc_perm shm_perm; /* Ownership and permissions */
size_t shm_segsz; /* Size of segment (bytes) */
time_t shm_atime; /* Last attach time */
time_t shm_dtime; /* Last detach time */
time_t shm_ctime; /* Last change time */
pid_t shm_cpid; /* PID of creator */
pid_t shm_lpid; /* PID of last shmat(2)/shmdt(2) */
shmatt_t shm_nattch; /* No. of current attaches */
...
};
共享内存函数
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
下面依次介绍一下上述函数的一些使用方法
shmget函数
功能:用来创建共享内存
原型:intshmget(key_t key, size_t size, intshmflg);
参数:
key:这个共享内存段名字
size:共享内存大小
shmflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的
返回值:成功返回一个非负整数,即该共享内存段的标识码;失败返回-1
shmat函数
功能:将共享内存段连接到进程地址空间
原型:void *shmat(intshmid, const void *shmaddr, intshmflg);
参数:
shmid: 共享内存标识
shmaddr:指定连接的地址
shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY
返回值:成功返回一个指针,指向共享内存第一个节;失败返回-1
shmaddr为NULL,核心自动选择一个地址
shmaddr不为NULL且shmflg无SHM_RND标记,则以shmaddr为连接地址。
shmaddr不为NULL且shmflg设置了SHM_RND标记,则连接的地址会自动向下调整为SHMLBA的整数倍。公式:shmaddr - (shmaddr % SHMLBA)
shmflg=SHM_RDONLY,表示连接操作用来只读共享内存
shmdt函数
功能:将共享内存段与当前进程脱离
原型:intshmdt(const void *shmaddr);
参数:
shmaddr: 由shmat所返回的指针
返回值:成功返回0;失败返回-1
注意:将共享内存段与当前进程脱离不等于删除共享内存段
shmctl函数
功能:用于控制共享内存
原型:intshmctl(intshmid, intcmd, structshmid_ds *buf);
参数:
shmid:由shmget返回的共享内存标识码
cmd:将要采取的动作(有三个可取值)
buf:指向一个保存着共享内存的模式状态和访问权限的数据结构
返回值:成功返回0;失败返回-1

生成共享内存示例代码:
#include<stdio.h>
#include<stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include<string.h>
#include<errno.h> typedef struct _Teacher
{
char name[];
int age;
}Teacher; int main(int argc, char *argv[])
{
int ret = ;
int shmid;
//创建共享内存 ,相当于打开文件,文件不存在则创建
shmid = shmget(0x2234, sizeof(Teacher), IPC_CREAT | );
if (shmid == -)
{
perror("shmget err");
return errno;
}
printf("shmid:%d \n", shmid);
Teacher *p = NULL;
//将共享内存段连接到进程地址空间
p = shmat(shmid, NULL, );//第二个参数shmaddr为NULL,核心自动选择一个地址
if (p == (void *)- )
{
perror("shmget err");
return errno;
}
strcpy(p->name, "aaaa");
p->age = ;
//将共享内存段与当前进程脱离
shmdt(p); printf("键入1 删除共享内存,其他不删除\n"); int num;
scanf("%d", &num);
if (num == )
{
//用于控制共享内存
ret = shmctl(shmid, IPC_RMID, NULL);//IPC_RMID为删除内存段
if (ret < )
{
perror("rmerrr\n");
}
} return ;
}
执行程序过程及测试步骤如下图:

获取共享内存示例代码:
#include<stdio.h>
#include<stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include<string.h>
#include<errno.h> typedef struct _Teacher
{
char name[];
int age;
}Teacher; int main(int argc, char *argv[])
{
int ret = ;
int shmid;
//shmid = shmget(0x2234, sizeof(Teacher), IPC_CREAT |IPC_EXCL | 0666);
//打开获取共享内存
shmid = shmget(0x2234, , );
if (shmid == -)
{
perror("shmget err");
return errno;
}
printf("shmid:%d \n", shmid);
Teacher *p = NULL;
//将共享内存段连接到进程地址空间
p = shmat(shmid, NULL, );
if (p == (void *)- )
{
perror("shmget err");
return errno;
} printf("name:%s\n", p->name);
printf("age:%d \n", p->age);
//将共享内存段与当前进程脱离
shmdt(p); printf("键入1 程序暂停,其他退出\n"); int num;
scanf("%d", &num);
if (num == )
{
pause();
}
return ;
}
执行程序步骤以及演示结果:

linux共享内存简单介绍以及编码演示的更多相关文章
- Linux 程序设计1:深入浅出 Linux 共享内存
笔者最近在阅读Aerospike 论文时,发现了Aerospike是利用了Linux 共享内存机制来实现的存储索引快速重建的.这种方式比传统利用索引文件进行快速重启的方式大大提高了效率.(减少了磁盘 ...
- Linux守护进程简单介绍和实例具体解释
Linux守护进程简单介绍和实例具体解释 简单介绍 守护进程(Daemon)是执行在后台的一种特殊进程.它独立于控制终端而且周期性地执行某种任务或等待处理某些发生的事件.守护进程是一种非常实用的进程. ...
- Linux curl使用简单介绍
在两台新搬迁的微信服务器上执行命令: curl -H "Content-Type: application/json" -d '{"partner_no":&q ...
- linux 共享内存shm_open实现进程间大数据交互
linux 共享内存shm_open实现进程间大数据交互 read.c #include <sys/types.h> #include <sys/stat.h> #includ ...
- linux 共享内存
共享内存是最高效的IPC机制,因为它不涉及进程之间的任何数据传输.这种高效带来的问题是,我们必须用其他手段来同步进程对共享内存的访问,否则会产生竞态条件.所以,共享内存通常和其他进程间通信方式一起使用 ...
- Linux共享内存(二)
Linux共享内存编程实例 原文链接:http://blog.csdn.net/pcliuguangtao/article/details/6526119 /*共享内存允许两个或多个进程进程共享同一块 ...
- Linux共享内存(一)
inux系统编程我一直看 <GNU/LINUX编程指南>,只是讲的太简单了,通常是书和网络上的资料结合着来掌握才比较全面 .在掌握了书上的内容后,再来都其他资料 . 原文链接 http:/ ...
- linux 共享内存实现
说起共享内存,一般来说会让人想起下面一些方法:1.多线程.线程之间的内存都是共享的.更确切的说,属于同一进程的线程使用的是同一个地址空间,而不是在不同地址空间之间进行内存共享:2.父子进程间的内存共享 ...
- Linux 共享内存编程
共享内存允许系统内两个或多个进程共享同一块内存空间,并且数据不用在客户进程和服务器进程间复制,因此共享内存是通信速度最快的一种IPC. 实现的机制简单描述如下:一个进程在系统中申请开辟了一块共享内存空 ...
随机推荐
- oracle常用操作命令总结
一. 默认安装带来的用户名/密码:--sys/change_on_install SYSDBA 或 SYSOPER 不能以 NORMAL 登录,可作为默认的系统管理员 --system/安装时输入的密 ...
- webPage logService 日志服务 剥离
[旧的场景]1.x.a.com指向负载均衡服务器ipL;2.代码所在的应用服务器ipA,ipB,ipC,运行nginx-phpFPM服务,提供2个服务: 2.1.应用服务器ipA,ipB,ipC中we ...
- Boss Group Worker Group NioEventLoopGroup
宜人贷蜂巢API网关技术解密之Netty使用实践 - honeycomb2017的博客 - CSDN博客 https://blog.csdn.net/honeycomb2017/article/det ...
- Spark 源码分析 -- Task
Task是介于DAGScheduler和TaskScheduler中间的接口 在DAGScheduler, 需要把DAG中的每个stage的每个partitions封装成task 最终把taskset ...
- 用Nginx反向代理Node.js
安装pm2 npm install pm2 -g ln -s /home/download/node-v8.11.1-linux-x64/lib/node_modules/pm2/bin/pm2 /u ...
- VS安装程序制作之MSI/EXE
MSI文件是Windows Installer的数据包,它实际上是一个数据库,包含安装一种产品所需要的信息和在很多安装情形下安装(和卸载)程序所需的指令和数据.MSI文件将程序的组成文件与功能关联起来 ...
- U盘安装CentOS7笔记
准备工具: 8G左右U盘; 最新版UltraISO; CentOS7光盘镜像; CentOS7的镜像文件可以在网易的开源镜像站或者阿里云的开源镜像站下载,地址分别是:http://mirrors.16 ...
- C的指针疑惑:C和指针13(高级指针话题)
传递命令行参数 C程序的main函数具有两个形参.第一个通常称为argc,代表命令行参数的数目. 第二个通常称为argv,它指向一组参数值.由于参数的数目并没有内在的限制,所以argv指向这组参数值( ...
- SQL Server 2008 sa用户可以登录,Windows身份验证无法登录
安装SQL Server 2008时一切正常,但是在启动时出现了问题.若使用SQL Server 身份验证,选择sa用户可以登录到系统,并正常使用.但是,若使用Windows身份验证,提示用户名或密码 ...
- PAT 1039 Course List for Student[难]
1039 Course List for Student (25 分) Zhejiang University has 40000 students and provides 2500 courses ...