一 共享内存

  共享内存是由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——共享内存的更多相关文章

  1. Linux学习笔记-文件系统和基本命令

    目录 分区设备文件名 分区 挂载 文件目录 文件处理命令 目录处理命令 硬件设备文件名 IDE硬盘 /dev/hd[a-d] USB硬盘 /dev/sd[a-p] 光驱 /dev/cdrom或者/de ...

  2. Linux 学习笔记之超详细基础linux命令 Part 14

    Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 13---------------- ...

  3. Intel® Media SDK Media Samples Linux 学习笔记(转)

    最近折腾intel media sdk,主要硬件平台是在HD4600的核显上进行测试,intel media sdk是intel提供的一种基于核显的硬件编解码的解决方案,之前已经有使用ffmpeg进行 ...

  4. Linux学习笔记——管道PIPE

    管道:当从一个进程连接数据流到另一个进程时,使用术语管道(pipe).# include <unistd.h> int pipe(int filedes[2]); //创建管道 pipe( ...

  5. Linux 学习笔记

    Linux学习笔记 请切换web视图查看,表格比较大,方法:视图>>web板式视图 博客园不能粘贴图片吗 http://wenku.baidu.com/view/bda1c3067fd53 ...

  6. linux学习笔记2-linux的常用命令

    第一篇博客:linux学习笔记1-ubuntu的安装与基本设置 之中,已经介绍了如何安装linux操作系统,以及一些基本的设置修改. 本篇博客主要介绍linux中的一些常用的终端命令 ======== ...

  7. Linux学习笔记(一)2015.4.13

    研究生由单片机转Linux学习 首先安装VMware虚拟机,用的是VMware 10.0 在VMware 10.0上安装视频上推荐的Red Hat Linux 5 安装后正式进入Linux学习 笔记1 ...

  8. linux —— 学习笔记(汇总)

    笔记目录:一.系统知识 和 基本概念                    二.常用操作                   三.系统管理(内存.设备.服务等管理)                   ...

  9. Linux学习笔记-林耐斯Notes-Linux就该这么学

    Linux学习笔记... 参考的优秀Linux网站: http://www.w3cschool.cn/linux/ http://www.linuxeye.com/ http://linux.vbir ...

随机推荐

  1. Unity3D 获得GameObject组件的方法

    Unity3D 获得GameObject组件的方法有几种,这里进行说明一下: 组件: 要获得这些组件,进行操作的话,绑定一个Movescipt 的C#组件,里面的获取方法为 void Update ( ...

  2. [Cookie] C#CookieHelper--C#操作Cookie的帮助类 (转载)

    点击下载 CookieHelper.rar 下面是代码大家看一下 /// <summary> /// 类说明:CookieHelper /// 联系方式:361983679 /// 更新网 ...

  3. jmeter压测app

    使用代理的方式,录制app端脚本,之后用jmeter压测就没啥好说的了 1.电脑端谷歌设置本地代理(端口号为8888) 2.jmeter设置HTTP代理服务器(端口号为8888) 3.手机端wifi设 ...

  4. 解决weblogic与系统时间相差8小时的问题

    解决weblogic与系统时间相差8小时的问题 在一般情况下weblogic与系统时间是很少会出现时间差的问题,但有可能在某一特定的情况下就会出现,如使用weblogic8版本时可能会出现时差问题: ...

  5. iOS中常用的第三方

    1. ZBarSDK 二维码.条形码 http://www.cnblogs.com/qingche/p/4242129.html

  6. C# 之【线程与进程】

    1.  引言 先来个比喻手法: 如果把上课的过程比作进程,那么每个学生就是一个线程,他们共享教室,即线程共享进程的内存空间.每一个时刻,只能一个学生问老师问题,老师回答完毕,轮到下一个.即线程在一个时 ...

  7. js日期格式,日期对象

    以对象为基准去使用方法, 围绕Date对象 var a = new Date() 返回当前的时间对象,可以使用内置的日期对象的方法 a.getFullYear(), a.getMonth(), a.g ...

  8. Cloudera Impala 之 ORDER BY without LIMIT currently not supported

    ERROR: NotImplementedException: ORDER BY without LIMIT currently not supported   impala中order by 需要l ...

  9. PHP开发APP接口---返回数据的封装类

    参考视频http://www.imooc.com/learn/163 <?php /** * app返回数据类 * 1.接受多维,缺少键名的数组, * 2.可由输入的format参数决定返回数据 ...

  10. Lsp修复

    打开电脑,进入命令提示符窗口,快捷键win+r.   在窗口中输入“cmd”进入命令符窗口.       在窗口中输入:输入netsh winsock reset,然后按下回车键.   然后稍等片刻, ...