IPC之共享内存
man 7 shm_overview
shm_overview - Overview of POSIX shared memory.
同样,SystemV实现的共享内存是旧的机制,但应用广泛;Posix标准提供了新的统一接口。
共享内存是由内核出于在多个进程间交换信息的目的而留出的一块内存区(段)。如果段的权限设置恰当,每个要访问该段内存的进程都可以把它映射到自己私有的地址空间中。如果一个进程更新了段中数据,那么其他进程立即回看到更新。由一个进程创建的段也可以由另一个进程读写。共享内存这一名称表达出是由多个进程分享对段及其保存的数据的访问权这一含义。共享内存很像内存映射文件。
Posix API:
shm_open, ftruncate, mmap, munmap, shm_unlink, close, fstat, fchown, fchmod.
System V API:
shmget,shmat,shmdt
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, int size, int flags);
flags可以是一个或多个IPC_CREAT、IPC_EXCL和一组权限位(模式)按位“或”的结果。权限位以八进制表示。IPC_EXCL确保如果段已经存在,执行失败,而不是返回一个已经存在的段的标示符。IPC_CREAT指出如果没有和key关联的段就应该创建一个新段。key既可以是IPC_PRIVATE也可以是ftok函数返回的一个关键字。参数size指定段的大小,但它以PAGE_SIZE的值为界,这个值是某种处理器本身页的大小(intel是4KB)。shmget成功返回段标识符,出错返回-1。
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h> #define BUFSZ 4096 int main(void)
{
int shmid; if((shmid = shmget(IPC_PRIVATE, BUFSZ, )) < )
{
perror("shmget");
exit(EXIT_FAILURE);
} printf("segment created: %d\n", shmid); system("ipcs -m\n"); exit(EXIT_SUCCESS);
}
~$./a.out
segment created: ------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 yuxi
0x00000000 yuxi
0x00000000 yuxi
shmget只是创建了共享内存区,进程要把它映射到自己的地址空间才能使用它,调用shmat完成。
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const char *shmaddr, int shmflg);
int shmdt(const void *shmaddr);
在函数shmat中,如果shmaddr为NULL,则内核会把段映射到调用进程的地址空间中它所选定的位置。假如shmaddr不为NULL,并且shmflg指定SHM_RND,则attach发生在附近的最小倍数SHMLBA。否则shmaddr必须是页对齐的地址。一般总是把shmaddr设置为0。flags可以为SHM_RDONLY,这意味着被附加的段是只读的。否则,被附加的段默认是可读写的。如果shmat调用成功,则返回附加了段的地址。否则,它返回-1并且设置errno变量。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h> int main(int argc, char *argv[])
{
int shmid;
char *shmbuf; if(argc != )
{
puts("USAGE: atshm <identifier>");
exit(EXIT_FAILURE);
}
shmid = atoi(argv[]); if((shmbuf = shmat(shmid, , )) < (char *))
{
perror("shmat");
exit(EXIT_FAILURE);
}
printf("segment attached at %p\n", shmbuf); system("ipcs -m"); if((shmdt(shmbuf)) < )
{
perror("shmdt");
exit(EXIT_FAILURE);
} puts("segment detached"); system("ipcs -m"); exit(EXIT_SUCCESS);
}
~$./a.out
segment attached at 0xb7709000 ------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 yuxi
0x00000000 yuxi
0x00000000 yuxi segment detached ------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 yuxi
0x00000000 yuxi
0x00000000 yuxi
使用举例:
include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <fcntl.h>
#include <ctype.h> #define BUFSZ 4096 int main(int argc, char **argv)
{
int shmid;
char *shmbuf;
int fd;
int i; if(argc != )
{
puts("USAGE: opshm <identifier>");
exit(EXIT_FAILURE);
}
shmid = atoi(argv[]); if((shmbuf = shmat(shmid, , )) < (char *))
{
perror("shmat");
exit(EXIT_FAILURE);
} if((shmbuf = malloc(sizeof(char) * BUFSZ)) < (char *))
{
perror("malloc");
exit(EXIT_FAILURE);
} for(i = ; i < BUFSZ; ++i)
{
shmbuf[i] = rand();
} fd = open("opshm.out", O_CREAT | O_WRONLY, );
write(fd, shmbuf, BUFSZ); free(shmbuf); exit(EXIT_SUCCESS);
}
创建shm举例
void *init_shm(void)
{
key_t key;
int shmid;
void *addr = NULL; key = ftok(SHM_PATH, SHM_PROJ);
if(key == -)
{
perror("ftok()");
return NULL;
} shmid = shmget(key, sizeof(struct shm_block), IPC_CREAT | );
if(shmid == -)
{
perror("shmget: ");
return NULL;
}
addr = shmat(shmid, , );
if (addr == (void *)-)
{
perror("shmat()");
return NULL;
} return addr;
}
通过命令ipcs -m可以查看共享内存信息。
注:大部分内容来自《GNU/LINUX编程指南》
IPC之共享内存的更多相关文章
- 进程间通信IPC之--共享内存
每个进程各自有不同的用户地址空间,任何一个进 程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲 区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲 ...
- Linux IPC之共享内存C 事例
Linux IPC之共享内存 标签: linuxrandomnull工作 2011-08-25 11:52 4123人阅读 评论(0) 收藏 举报 分类: Linux(3) 读书札记(3) 版权 ...
- System V IPC(3)-共享内存
一.概述 1.共享内存允许多个进程共享物理内存的同一块内存区. 2.与管道和消息队列不同,共享内存 ...
- System V IPC 之共享内存
IPC 是进程间通信(Interprocess Communication)的缩写,通常指允许用户态进程执行系列操作的一组机制: 通过信号量与其他进程进行同步 向其他进程发送消息或者从其他进程接收消息 ...
- 进程间通信——IPC之共享内存
共享内存是三个IPC机制中的一个.它允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在进行的进程之间传递数据的一种非常有效的方式. 大多数的共享内存的实现,都把由不同进程之间共享 ...
- 五十、进程间通信——System V IPC 之共享内存
50.1 共享内存 50.1.1 共享内存的概念 共享内存区域是被多个进程共享的一部分物理内存 多个进程都可把该共享内存映射到自己的虚拟内存空间.所有用户空间的进程若要操作共享内存,都要将其映射到自己 ...
- zabbix_agentd重装后启动时IPC和共享内存段问题
zabbix_agentd不知为啥被干掉后重装了zabbix,zabbix用户组id也变了. 重装zabbix后导致zabbix_agentd无法启动,两个问题 问题1: zabbix_agentd ...
- Linux IPC之共享内存
System V共享内存机制: shmget shmat shmdt shmctl 原理及实现: system V IPC机制下的共享内存本质是一段特殊的内存区域,进程间需要共享的数据被放在该共 ...
- Unix IPC之共享内存区(1)
1 共享内存区 共享内存区是可用IPC形式中最快的,只有映射和解除映射需要进入内核的系统调用,映射后对共享内存区的访问和修改不再需要系统调用(内核只要负责好页表映射和处理页面故障即可),但通常需要同步 ...
- System IPC 与Posix IPC(共享内存)
系统v(共享内存) 1.对于系统V共享内存,主要有以下几个API:shmget().shmat().shmdt()及shmctl(). 2.shmget()用来获得共享内存区域的ID,如果不存在指定的 ...
随机推荐
- 一步一步学RenderMonkey(3)——改良Phong光照模型 【转】
转载请注明出处: http://blog.csdn.net/tianhai110 改良后的Phong光照模型: 上一节实现的phong镜面光照模型,如果固定光源,移动视点(及matView 关联为ma ...
- [Python爬虫] 之二十八:Selenium +phantomjs 利用 pyquery抓取网站排名信息
一.介绍 本例子用Selenium +phantomjs爬取中文网站总排名(http://top.chinaz.com/all/index.html,http://top.chinaz.com/han ...
- 微信公众平台开发小记(ASP.NET)
微信的好东西,提供了很大的平台去发挥,公司最近推出微信公众账号,也接触了一些东西, 最终决定用asp.net来开发服务端程序. 微信公众平台的API很简单,利用XML来规范格式,并且所有的数据都在CD ...
- win 2003 / IIS6 部署网站的时候,文件IO操作、删除项目文件, 会导致IIS重启,Session丢失问题
项目中经常需要打些日志(文件IO读写操作),已记录调试.错误等信息.比较方便的有log4net等开源项目. 问题描述: 最近用win 2003 / IIS6,部署了一个2.0 的网站,在操作文件的时候 ...
- hdu4515小Q系列故事——世界上最遥远的距离
Problem Description 世界上最遥远的距离 不是生与死 而是我就站在你面前 你却不知道我爱你 世界上最遥远的距离 不是我就站在你面前你却不知道我爱你 而是明明知道彼此相爱 却不能在一起 ...
- Unity3.5 GameCenter基础教程(转载)
原地址: http://forum.unity3d.com/threads/116901-Game-Center-Support/page3 using UnityEngine; using Unit ...
- android与服务端通讯时使用到的GZIP压缩及解压
为了减小android项目与服务端进行通讯时的数据流量,我们可以使用GZIP对服务端传输的数据进行压缩,在android客户端解压.或在客户端压缩,在服务端解压.代码如下: android客户端的GZ ...
- PlayMaker 不支持过渡条件
Unity Animator 自带也支持过渡条件, 我看了下PlayMaker没有这个概念. 最近研究下PlayMaker,图形化编程的确很爽. 但是PlayMaker 始于与给一些策划进行流程设 ...
- 使用ipmitool 命令添加IPMI 界面的SMTP邮件服务器地址
目前要通过ipmitool工具在IPMI的界面上添加邮件服务器地址,该脚本如下 SMTP.sh #!/bin/bash ipmitool raw 0x32 0x78 0x01 0x01 0x00 0x ...
- Chrome Dev Editor:一个新的JavaScript和Dart IDE
在Google IO 2014期间,一位Google工程师带来了Chrome Dev Editor(CDE).该IDE用于创建面向桌面和移动设备的Chrome应用程序和Web应用程序.CDE支持Jav ...