一 共享内存

  共享内存是由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. (经典)tcp粘包分析

    转载自csdn:http://blog.csdn.net/zhangxinrun/article/details/6721495 这两天看csdn有一些关于socket粘包,socket缓冲区设置的问 ...

  2. Linq- ExcuteQuery用法

    DataContext.ExecuteQuery<TResult> 方法 (String, Object[]) 语法: public IEnumerable<TResult> ...

  3. window.event对象详细介绍

    1.event代表事件的状态,例如触发event对象的元素.鼠标的位置及状态.按下的键等等.event对象只在事件发生的过程中才有效.event的某些属性只对特定的事件有意义.比如,fromEleme ...

  4. 原始的JDBC操作

    -----------------------------根据配置文件---------------------------- package cn.gdpe.jdbc; import java.io ...

  5. TCP与UDP网络编程总结(一)

    (1):TCP网络编程 我们注意到服务端与客户端通信时是通过客户端的套接字相互通信的,那么服务端的套接字主要是干什么用的呢? TCP服务端设置监听套接字时 int listen(int sock,in ...

  6. GridView获取单个单元格的值

    0.GridView中的所有数据都存储在Rows集合中,可以通过Rows的Cell属性获取单个单元格的值:如果某个单元格包含其他控件,则通过使用单元格的 Controls 集合,从单元格检索控件:如果 ...

  7. DATE 使用

    DATE 使用 标签(空格分隔): SHELL 使用shell处理文本时经常要使用date,但各种参数经常忘,记录在此: #date 获取当前时间 #date -d "-1 week&quo ...

  8. Balanced Lineup

      Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 49061   Accepted: 22975 Case Time Lim ...

  9. caffe---测试模型分类结果并输出(python )

    当训练好一个model之后,我们通常会根据这个model最终的loss和在验证集上的accuracy来判断它的好坏.但是,对于分类问题,我们如果只是知道整体的分类正确率 显然还不够,所以只有知道模型对 ...

  10. 用VS2010编写的C++程序,在其他电脑上无法运行,提示缺少mfc100.dll的解决办法

    问题: 在自己电脑上用VS2010编写的VC++程序(使用MFC库),不能在其他电脑上运行.双击提示: "无法启动此程序,因为计算机中丢失mfc100.dll 尝试重新安装该程序以解决此问题 ...