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. 实现的机制简单描述如下:一个进程在系统中申请开辟了一块共享内存空 ...
随机推荐
- style,currentStyle和getComputedStyle的区别
样式表有三种方式 内嵌样式(inline Style) :是写在Tag里面的,内嵌样式只对所有的Tag有效. 内部样式(internal Style Sheet):是写在HTML的里面的,内部样式只对 ...
- 巨蟒python全栈开发flask10 项目开始2
1.websocket异常处理 出现上图报错的原因是什么? 原因是:websocket断开了,所以报错 19行接收的msg是None值,所以报错. 打开一个文件,点击发送音乐,出现上面的内容: 客户端 ...
- [genome shell]标题栏优化
参考地址:https://wiki.archlinux.org/index.php/GNOME_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)#.E4.BB.8E.E5. ...
- Storm-源码分析-LocalState (backtype.storm.utils)
LocalState A simple, durable, atomic K/V database. *Very inefficient*, should only be used for occas ...
- JavaScript自定义函数
js对象转成用&拼接的请求参数(转) var parseParam=function(param, key){ var paramStr=""; if(param inst ...
- 剑指Offer——二叉树的下一个结点
题目描述: 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 分析: 如果该结点存在右子树,那么返回右子树的最左结 ...
- 如何在 cmd 中打开设备管理器,如何找到打开其他设备的命令?
Win + R 组合键后,输入 devmgmt.msc 即可. 任意打开一个软件,然后查看其命令行,找到该程序的实际进程名即可. 注意:需要打开的程序需要放在设置过环境变量的目录,确保执行 cmd 时 ...
- Linux SSH免登录配置总结(转)
转载请出自出处:http://eksliang.iteye.com/blog/2187265 一.原理 我们使用ssh-keygen在ServerA上生成私钥跟公钥,将生成的公钥拷贝到远程机器Serv ...
- SDUT3141:Count(哈希)好题
题目:传送门 题目描述 You are given an integer array s[] and are asked to count how many positions a, b, c and ...
- a=a+1背后的内存模型和CPU高速缓存
学过JAVA的人都知道,程序运行过程中的临时数据,都是从外部存储设备调入内存(物理内存)中,再进行读写操作的.而计算机在执行程序时,对程序的每条指令都是在CPU中执行的,而指令的执行,势必涉及到对数据 ...