Linux学习笔记27——共享内存
一 共享内存
共享内存是由IPC为进程创建的一个特殊的地址范围,它将出现在该进程的地址空间中。其他进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址。如果某个进程向共享内存写入了数据,所做的改动将立刻被可以访问同一段共享内存的任何其他进程看到。
二 相关函数
#include <sys/shm.h>
//shmget创建共享内存
int shmget(key_t key, //为共享内存段命名
size_t size, //以字节为单位指定需要共享的内存容量
int shmflg //权限标志。允许一个进程创建的共享内存可以被共享内存的创建者所拥有的进程写入,同时其他用户创建的进程只能读取该共享内存。
); //如果共享内存创建成功,返回一个非负整数,即共享内存标识符,如果失败,就返回-1 //shmat将共享内存连接它在程序进入临界区域时设置信号量到一个进程的地址空间中
void *shmat(int shm_id, //由shmget返回的共享内存标识符
const void *shm_addr, //指定的是共享内存连接到当前进程中的地址位置,它通常是一个空指针,表示让系统来选择共享内存出现的地址
int shmflg //一组位标志。通常设为0,让系统来选择一个地址,否则就会使应用程序对硬件的依赖性过高
); //如果调用成功,返回一个指向共享内存第一个字节的指针,如果失败,返回-1 //shmctl控制共享内存
int shmctl(int shm_id, //shmget返回的共享内存标识符
int cmd, //要采取的动作,可以取3个值: IPC_STAT,IPC_SET,IPC_RMID
struct shmid_ds *buf //是一个指向包含共享内存模式和访问权限的结构
); //成功时返回0,失败时返回-1 //shmdt将共享内存从当前进程中分离
int shmdt(const void *shm_addr); //参数是shmat返回的地址指针。成功时返回0,失败时返回-1
shmctl中第二个参数的取值:
IPC_STAT:把shmid_ds结构中的数据设置为共享内存的当前关联值
IPC_SET:如果进程有足够的权限,就把共享内存的当前关联值设置为shmid_ds结构中给出的值
IPC_RMID:删除共享内存段
struct shmid_ds{
uid_t shm_perm.uid;
uid_t shm_perm.gid;
mode_t shm_perm.mode;
}
三 例子
shm_com.h
#define TEXT_SZ 2048
struct shared_use_st{
int written_by_you;
char some_text[TEXT_SZ];
};
shm1.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h> #include <sys/shm.h>
#include "shm_com.h" int main(){
int running =;
void *shared_memory=(void*);
struct shared_use_st *shared_stuff;
int shmid; srand((unsigned int)getpid());
shmid=shmget((key_t),sizeof(struct shared_use_st),|IPC_CREAT); if(shmid==-){
fprintf(stderr,"shmget failed\n");
exit(EXIT_FAILURE);
}
//现在可以让程序访问这个共享内存
shared_memory=shmat(shmid,(void*),);
if(shared_memory==(void*)-){
fprintf(stderr,"shmat failed\n");
exit(EXIT_FAILURE);
}
printf("Memory attached at %X\n",(int)shared_memory); //将shared_memory分配给shared_stuff,然后它输出written_by_you中的文本
shared_stuff=(struct shared_use_st *)shared_memory;
shared_stuff->written_by_you=;
while(running){
if(shared_stuff->written_by_you){
printf("You wrote:%s",shared_stuff->some_text);
sleep(rand()%);
shared_stuff->written_by_you=;
if(strncmp(shared_stuff->some_text,"end",)==){
running=;
}
}
}
if(shmdt(shared_memory)==-){
fprintf(stderr,"shmdt failed\n");
exit(EXIT_FAILURE);
}
if(shmctl(shmid,IPC_RMID,)==-){
fprintf(stderr,"shmctl(IPC_RMID) failed\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
shm2.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> #include <sys/shm.h>
#include "shm_com.h" int main(){
int running=;
void *shared_memory=(void *);
struct shared_use_st *shared_stuff;
char buffer[BUFSIZ];
int shmid; shmid=shmget((key_t),sizeof(struct shared_use_st),|IPC_CREAT); if(shmid==-){
fprintf(stderr,"shmget failed\n");
exit(EXIT_FAILURE);
}
shared_memory=shmat(shmid,(void*),); if(shared_memory==(void *)-){
fprintf(stderr,"shmat failed\n");
exit(EXIT_FAILURE);
}
printf("Memory attached at %X\n",(int)shared_memory); shared_stuff=(struct shared_use_st *)shared_memory;
while(running){
while(shared_stuff->written_by_you==){
sleep();
printf("Waiting for client...\n");
}
printf("Enter some text:");
fgets(buffer,BUFSIZ,stdin);
strncpy(shared_stuff->some_text,buffer,TEXT_SZ);
shared_stuff->written_by_you=; if(strncmp(buffer,"end",)==){
fprintf(stderr,"shmdt failed\n");
exit(EXIT_FAILURE);
}
}
if(shmdt(shared_memory)==-){
fprintf(stderr,"shmdt failed\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
Linux学习笔记27——共享内存的更多相关文章
- Linux学习笔记-文件系统和基本命令
目录 分区设备文件名 分区 挂载 文件目录 文件处理命令 目录处理命令 硬件设备文件名 IDE硬盘 /dev/hd[a-d] USB硬盘 /dev/sd[a-p] 光驱 /dev/cdrom或者/de ...
- Linux 学习笔记之超详细基础linux命令 Part 14
Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 13---------------- ...
- Intel® Media SDK Media Samples Linux 学习笔记(转)
最近折腾intel media sdk,主要硬件平台是在HD4600的核显上进行测试,intel media sdk是intel提供的一种基于核显的硬件编解码的解决方案,之前已经有使用ffmpeg进行 ...
- Linux学习笔记——管道PIPE
管道:当从一个进程连接数据流到另一个进程时,使用术语管道(pipe).# include <unistd.h> int pipe(int filedes[2]); //创建管道 pipe( ...
- Linux 学习笔记
Linux学习笔记 请切换web视图查看,表格比较大,方法:视图>>web板式视图 博客园不能粘贴图片吗 http://wenku.baidu.com/view/bda1c3067fd53 ...
- linux学习笔记2-linux的常用命令
第一篇博客:linux学习笔记1-ubuntu的安装与基本设置 之中,已经介绍了如何安装linux操作系统,以及一些基本的设置修改. 本篇博客主要介绍linux中的一些常用的终端命令 ======== ...
- Linux学习笔记(一)2015.4.13
研究生由单片机转Linux学习 首先安装VMware虚拟机,用的是VMware 10.0 在VMware 10.0上安装视频上推荐的Red Hat Linux 5 安装后正式进入Linux学习 笔记1 ...
- linux —— 学习笔记(汇总)
笔记目录:一.系统知识 和 基本概念 二.常用操作 三.系统管理(内存.设备.服务等管理) ...
- Linux学习笔记-林耐斯Notes-Linux就该这么学
Linux学习笔记... 参考的优秀Linux网站: http://www.w3cschool.cn/linux/ http://www.linuxeye.com/ http://linux.vbir ...
随机推荐
- php 半角与全角相关的正则
半角的全部确认,带小初音的确认法则 ^[ア-ン゙゚ァ-ョッヲー -]+$ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset// ...
- KinSlideshow参数设置说明
[引用来自:http://blog.sina.com.cn/s/blog_4f4f4a5901014zn1.html] Jquery.KinSlideshow参数设置说明: 附:所有参数列表 in ...
- 《你不常用的c#之一》:略谈unsafe
转自csdn:http://blog.csdn.net/robingaoxb/article/details/6199508 msdn里讲到: “在 C# 中很少需要使用指针,但仍有一些需要使用的情况 ...
- 3DTouch
3DTouch 一.主屏按压(Home Screen Quik Actions) 1.静态标签 在info.plist文件中新增项 关键字 意义 UIApplicationShortcutItems ...
- JavaScript OOP 创建对象的7种方式
我写JS代码,可以说一直都是面向过程的写法,除了一些用来封装数据的对象或者jQuery插件,可以说对原生对象了解的是少之又少.所以我拿着<JavaScript高级程序设计 第3版>恶补了一 ...
- cvThreshold()函数理解
对图像二值化函数cvThreshold的理解 Threshold 对数组元素进行固定阈值操作 void cvThreshold( const CvArr* src, CvArr* dst, doubl ...
- sizeof()用法
参考:sizeof_百度百科 sizeof()用法汇总(经典) 声明:本文是笔者抽出对自己有用的细节,对前两文的总结. 1.sizeof概念 sizeof是C语言中判断数据类型或者表达式长度符:不是一 ...
- WebApi学习总结系列第四篇(路由系统)
由于工作的原因,断断续续终于看完了<ASP.NET Web API 2 框架揭秘>第二章关于WebApi的路由系统的知识. 路由系统是请求消息进入Asp.net WebApi的第一道屏障, ...
- iOS 中KVC、KVO、NSNotification、delegate 总结及区别-b
1.KVC,即是指 NSKeyValueCoding,一个非正式的Protocol,提供一种机制来间接访问对象的属性.而不是通过调用Setter.Getter方法访问.KVO 就是基于 KVC 实现的 ...
- 关于Android中传递数据的一些讨论--备用
在Android中编写过程序的开发人员都知道.在Activity.Service等组件之间传递数据(尤其是复杂类型的数据)很不方便.一般可以使用Intent来传递可序列化或简单类型的数据.看下面的代码 ...