Linux 共享内存编程
共享内存允许系统内两个或多个进程共享同一块内存空间,并且数据不用在客户进程和服务器进程间复制,因此共享内存是通信速度最快的一种IPC。
实现的机制简单描述如下:一个进程在系统中申请开辟了一块共享内存空间,然后使用这个共享内存空间的各个进程分别打开这个共享内存空间,并将这个内存空间映射到自己的进程空间上,这样各个进程就可以共同使用这个共享内存空间,就如同使用自己进程地址空间的内存一样。
要实现共享内存空间,内核做了许多工作:比如给每个共享内存块分发一个“身份证”、允许用户进程将共享内存映射到各自的地址空间上、在进程提出申请以后将共享内存和进程地址空间脱离,并在适当的时候讲共享内存删除,让其回到可以被创建的状态。
用户利用共享内存实现进程间的通信,实际上就是使用内核提供的服务完成对共享内存的建立、映射、脱离、删除等。当建立并映射成功以后,进程间就能通过共享内存实现数据的交互。下面就分别介绍内核提供的服务:
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 函数
shmget 函数实现共享内存的建立或者打开。当共享内存的键值key 尚未存在时,调用这个函数并且指定shmflg 参数为IPC_CREAT 可以创建一个大小为 size 的共享内存空间。假设key指定的共享内存已经存在,调用这个函数可以打开这个共享内存,但不会创建。键值的获取可以利用 ftok(),该函数的使用在博主的另一篇文章里http://www.cnblogs.com/linzizhang/p/4544794.html中有介绍。
shmat 函数
该函数将一个共享内存空间映射到调用进程的地址空间上,并且返回在进程地址空间中的地址。用户拿到改地址后就可以通过这个地址间接的访问共享内存。shmid 参数就是shmget 函数的返回值,shmaddr 参数实际上是指出了共享内存映射到进程地址空间上的位置,但是我们一般不会指定这个地址,而是令其为NULL ,让内核选择一个合适的地址。shmflg 参数是配合着shmaddr 参数使用的,在shmaddr 为NULL时就变得没有实际意义,因此通常指定为0。
shmdt 函数
这个函数将一个进程已经映射了的共享内存脱离进程地址空间。shmaddr 参数就是在进程地址空间的地址,实际就是shmat 函数的返回值。
shmctl 函数
此函数实际上有很多的功能,但是我们通长用它将一个已经创建了的共享内存删除,所谓删除实际就是将它放回可以被创建的共享内存队列中。指定cmd 参数为IPC_RMID,就可以将shmid键值指定的共享内存删除,而buf实际上是可以获取这共享内存在内核中的状态,如果不想了解可以指定为0。
共享内存通信使用到的系统服务就这么多,下面给出一个测试范例。该范例由两个进程组成,进程write将键盘上输入的字符串存储到共享内存,read进程将共享内存中的数据读出来,再西融入显示器显示。
write进程代码:
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h> #define TEXT_SZ 2048 struct shared_use_st
{
int written_by_you;
char some_text[TEXT_SZ];
}; int main(int argc,char **argv)
{ key_t key;
int shmid;
struct shared_use_st *space;
int running = ;
char buffer[TEXT_SZ];
//creat shared memory
key = ftok("/home/application/shared_memory",); shmid = shmget(key,sizeof(struct shared_use_st),IPC_CREAT); //attach share memory to space
space = (struct shared_use_st *)shmat(shmid,NULL,); //write datas to space
while(running)
{
while(space->written_by_you==)
{
sleep();
}
printf("Input strings:");
fgets(buffer,TEXT_SZ,stdin);
strncpy(space->some_text,buffer,TEXT_SZ);
space->written_by_you = ;
if(strncmp(buffer,"end",)==)
{
running = ;
} } //dis_attach to space
shmdt((const void *)space);
//distroy shared memory
// shmctl(shmid,IPC_RMID); return ;
}
read进程代码:
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h> #define TEXT_SZ 2048
struct shared_use_st
{
int written_by_you; //标志用来标明write进程是否写入了数据 written_by_you==1,写入数据,且read进程还没读走
char some_text[TEXT_SZ];
}; int main()
{
key_t key;
int shmid;
struct shared_use_st *space;
int running = ;
char buffer[TEXT_SZ];
//打开共享内存
key = ftok("/home/application/shared_memory",); shmid = shmget(key,sizeof(struct shared_use_st),IPC_CREAT); //映射共享内存
space = (struct shared_use_st *)shmat(shmid,NULL,); //读取数据
while(running)
{
if(space->written_by_you==)
{
strncpy(buffer,space->some_text,TEXT_SZ);
space->written_by_you = ;
printf("Recieved string :%s",buffer);
}
if(strncmp(buffer,"end",)==)
{
running = ;
} } //断开映射
shmdt((const void *)space); //删除共享内存
shmctl(shmid,IPC_RMID,); return ; }
Linux 共享内存编程的更多相关文章
- Linux共享内存编程实例
/*共享内存允许两个或多个进程进程共享同一块内存(这块内存会映射到各个进程自己独立的地址空间) 从而使得这些进程可以相互通信. 在GNU/Linux中所有的进程都有唯一的虚拟地址空间,而共享内存应用编 ...
- Linux共享内存(二)
Linux共享内存编程实例 原文链接:http://blog.csdn.net/pcliuguangtao/article/details/6526119 /*共享内存允许两个或多个进程进程共享同一块 ...
- Linux 程序设计1:深入浅出 Linux 共享内存
笔者最近在阅读Aerospike 论文时,发现了Aerospike是利用了Linux 共享内存机制来实现的存储索引快速重建的.这种方式比传统利用索引文件进行快速重启的方式大大提高了效率.(减少了磁盘 ...
- linux 共享内存shm_open实现进程间大数据交互
linux 共享内存shm_open实现进程间大数据交互 read.c #include <sys/types.h> #include <sys/stat.h> #includ ...
- linux 共享内存
共享内存是最高效的IPC机制,因为它不涉及进程之间的任何数据传输.这种高效带来的问题是,我们必须用其他手段来同步进程对共享内存的访问,否则会产生竞态条件.所以,共享内存通常和其他进程间通信方式一起使用 ...
- Linux共享内存(一)
inux系统编程我一直看 <GNU/LINUX编程指南>,只是讲的太简单了,通常是书和网络上的资料结合着来掌握才比较全面 .在掌握了书上的内容后,再来都其他资料 . 原文链接 http:/ ...
- linux 共享内存实现
说起共享内存,一般来说会让人想起下面一些方法:1.多线程.线程之间的内存都是共享的.更确切的说,属于同一进程的线程使用的是同一个地址空间,而不是在不同地址空间之间进行内存共享:2.父子进程间的内存共享 ...
- Linux共享内存
1.什么是共享内存在前面讲虚拟内存机制时,有讲到Linux的内存映射机制:初始化虚拟内存区域时,会把虚拟内存和磁盘文件对象对应起来.由于内存映射机制,一个磁盘文件对象可被多个进程共享访问,也可被多个进 ...
- 修改linux共享内存大小
这是实际linux系统显示的实际数据: beijibing@bjb-desktop:/proc/sys/kernel$ cat shmmax 33554432 beijibing@bjb-deskt ...
随机推荐
- openstack liberty 版本按照官方文档手动整合 完成后 基于dashboard-horizon 创建虚拟机报错 用CL却是成功的 网络等验证都是正确的通过启动的虚拟实例测试以成功
- 一个NB的安全认证机制
这是一个NB的安全认证机制. 1.这是一个安全认证机制 2.可以防止黑客截获到客户端发送的请求消息,避免了黑客冒充客户端向服务器发送操作的请求. 原理与步骤: 1.客户端与服务器端都会放着一份验证用的 ...
- Linux下SVN命令总结
目录 一.从版本库获取信息... 1 二.从版本库到本地... 2 三.从本地到版本库... 2 四.高级应用... 4 一.从版本库获取信息 svn help command 获取子命令说明 svn ...
- 怎样在Yii中显示静态页
在web应用中,我们经产更需要显示静态页,如“关于我们”等,这些文件通常是静态页,通常有如下几种处理方法: 1.把独立的html文件存在Web服务器能直接访问的目录下.这种方案的缺点是很难维护网页布局 ...
- java使用batik转换svg文件
svg是一种矢量图片格式,用来保存高保真的图片.我们可以用编辑器打开svg,我们可以看到svg文件其实就是一个xml文件,这种文件浏览器也可以识别.因此要查看svg用现成的浏览器就可以了.值得庆幸的是 ...
- poj 3608 Bridge Across Islands
题目:计算两个不相交凸多边形间的最小距离. 分析:计算几何.凸包.旋转卡壳.分别求出凸包,利用旋转卡壳求出对踵点对,枚举距离即可. 注意:1.利用向量法判断旋转,而不是计算角度:避免精度问题和TLE. ...
- Java Development Kit(JDK) 8 新特性(简述)
一.接口的默认方法 Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 default关键字即可,这个特征又叫做扩展方法. 示例如下: interface Formula { calcul ...
- linux使用FIO测试磁盘的iops 【转载】
linux使用FIO测试磁盘的iops 2013-09-23 10:59:21 分类: LINUX FIO是测试IOPS的非常好的工具,用来对硬件进行压力测试和验证,支持13种不同的I/O引擎,包括 ...
- thymelef 布局 fragment
需求:布局页面, 把首页分成四个页面: header footer ,content ,aside ,从githua 下载的原型, 所有内容是在一起的,这里拆分, 重用, 减少代码量 做法: 新建页 ...
- java 图片压缩 剪切 水印 转换 黑白 缩放
专注java已6年,欢迎加入java核心技术QQ群:135138817,每周五晚有群主进行技术讲座. import java.awt.AlphaComposite; import java.awt.C ...