System V共享内存机制: shmget  shmat  shmdt  shmctl

原理及实现:

system V IPC机制下的共享内存本质是一段特殊的内存区域,进程间需要共享的数据被放在该共享内存区域中,所有需要访问该共享区域的进程都要把该共享区域映射到本进程的地址空间中去。这样一个使用共享内存的进程可以将信息写入该空间,而另一个使用共享内存的进程又可以通过简单的内存读操作获取刚才写入的信息,使得两个不同进程之间进行了一次信息交换,从而实现进程间的通信。

共享内存允许一个或多个进程通过同时出现在它们的虚拟地址空间的内存进行通信,而这块虚拟内存的页面被每个共享进程的页表条目所引用,同时并不需要在所有进程的虚拟内存都有相同的地址。进程对象对于共享内存的访问通过key(键)来控制,同时通过key进行访问权限的检查。

函数定义如下:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

key_t ftok(const char *pathname, int proj_id);

函数ftok用于创建一个关键字,可以用该关键字关联一个共享内存段。

参数pathname为一个全路径文件名,并且该文件必须可访问。

参数proj_id通常传入一非0字符

通过pathname和proj_id组合可以创建唯一的key

如果调用成功,返回一关键字,否则返回-1

int shmget(key_t key, int size, int shmflg);

函数shmget用于创建或打开一共享内存段,该内存段由函数的第一个参数唯一创建。函数成功,则返回一个唯一的共享内存标识号(相当于进程号,唯一的标识着共享内存),失败返回-1。

参数key是一个与共享内存段相关联关键字,如果事先已经存在一个与指定关键字关联的共享内存段,则直接返回该内存段的标识,表示打开,如果不存在,则创建一个新的共享内存段。key的值既可以用ftok函数产生,也可以是IPC_RPIVATE(用于创建一个只属于创建进程的共享内存,主要用于父子通信),表示总是创建新的共享内存段;

参数size指定共享内存段的大小,以字节为单位;

参数shmflg是一掩码合成值,可以是访问权限值与(IPC_CREAT或IPC_EXCL)的合成。IPC_CREAT表示如果不存在该内存段,则创建它。IPC_EXCL表示如果该内存段存在,则函数返回失败结果(-1)。如果调用成功,返回内存段标识,否则返回-1

void *shmat(int shmid, const void *shmaddr, int shmflg);

函数shmat将共享内存段映射到进程空间的某一地址

参数shmid是共享内存段的标识  通常应该是shmget的成功返回值

参数shmaddr指定的是共享内存连接到当前进程中的地址位置。通常是NULL,表示让系统来选择共享内存出现的地址。

参数shmflg是一组位标识,通常为0即可。

如果调用成功,返回映射后的进程空间的首地址,否则返回(char *)-1。

int shmdt(const void *shmaddr);

函数shmdt用于将共享内存段与进程空间分离

参数shmaddr通常为shmat的成功返回值。

函数成功返回0,失败时返回-1.注意,将共享内存分离并没删除它,只是使得该共享内存对当前进程不在可用。

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

函数shmctl是共享内存的控制函数,可以用来删除共享内存段

参数shmid是共享内存段标识 通常应该是shmget的成功返回值

参数cmd是对共享内存段的操作方式,可选为IPC_STAT,IPC_SET,IPC_RMID。通常为IPC_RMID,表示删除共享内存段。

参数buf是表示共享内存段的信息结构体数据,通常为NULL。

例如shmctl(kshareMem,IPC_RMID,NULL)表示删除调共享内存段kHareMem

示例:

shm1.c

 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h> int main(int *argc, char *argv[])
{
key_t my_key;
int my_shm;
char *pstr; //1,创建一个关键字,使其关联一个共享内存段,返回关键字
my_key = ftok("./temp.c",); //2,创建或打开一个共享内存段,返回共享内存段标志号
my_shm = shmget(my_key,, | IPC_CREAT);
if(my_shm == -)
{
printf("shmget error!\n");
exit();
} //3,将共享内存段映射到进程空间的某一地址,返回映进程射空间的首地址
pstr = (char*)shmat(my_shm,NULL,); strcpy(pstr,"Hello world!\n");
sleep();
printf("recv from 2:%s\n",pstr); //4,将共享内存段与进程空间分离
shmdt(pstr); //5,删除共享内存段
shmctl(my_shm,IPC_RMID,NULL); return ;
}

shm2.c

 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h> int main(int *argc, char *argv[])
{
key_t my_key;
int my_shm;
char *pstr; //1,创建关键字
my_key = ftok("./temp.c",); //2,创建或打开共享内存段
my_shm = shmget(my_key,,);
if(my_shm == -)
{
printf("Shmget error!\n");
exit();
} //3,将共享内存段映射到某一进程空间
pstr = (char*)shmat(my_shm,NULL,);
printf("recv from 1:%s\n",pstr);
strcpy(pstr,"How are you!\n"); //4将共享内存段与进程空间分离
shmdt(pstr); return ;
}

Linux IPC之共享内存的更多相关文章

  1. Linux IPC之共享内存C 事例

    Linux IPC之共享内存 标签: linuxrandomnull工作 2011-08-25 11:52 4123人阅读 评论(0) 收藏 举报  分类: Linux(3)  读书札记(3)  版权 ...

  2. Linux IPC POSIX 共享内存

    模型 #include <unistd.h> //for fstat() #include <sys/types.h> //for fstat() #include <s ...

  3. Linux信号量同步共享内存实验.

    Linux信号量同步共享内存实验. Linux信号量同步共享内存实验. 简述 程序流程 信号量和共享内存的系统函数 信号量系统函数及接口 共享内存系统函数及接口 写程序 读程序 简述 本文主要内容是自 ...

  4. Linux环境进程间通信: 共享内存

    Linux环境进程间通信: 共享内存 第一部分 共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式.两个不同进程A.B共享内存的意思是,同一块物理内存被映射到进程A.B各自的进程地址空间.进 ...

  5. 进程间通信IPC之--共享内存

    每个进程各自有不同的用户地址空间,任何一个进 程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲 区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲 ...

  6. Linux进程间通信—使用共享内存

    Linux进程间通信-使用共享内存 转自: https://blog.csdn.net/ljianhui/article/details/10253345 下面将讲解进程间通信的另一种方式,使用共享内 ...

  7. 【Linux 应用编程】进程管理 - 进程间通信IPC之共享内存 mmap

    IPC(InterProcess Communication,进程间通信)是进程中的重要概念.Linux 进程之间常用的通信方式有: 文件:简单,低效,需要代码控制同步 管道:使用简单,默认阻塞 匿名 ...

  8. Linux下IPC之共享内存的使用方法

    基本参考 <Unix环境高级编程>第14.9节共享内存来学习. 参考blog:https://blog.csdn.net/weixin_45794138/article/details/1 ...

  9. linux进程间通信之共享内存篇

    本文是对http://www.cnblogs.com/andtt/articles/2136279.html中共享内存(上)的进一步阐释说说明 1 共享内存的实现原理 共享内存是linux进程间通讯的 ...

随机推荐

  1. J2SE 8的输入输出--读取/写入文本文件和读取/写入二进制数据

    读取/写入文本文件 // 1. 文本输入 // (1) 短小文本直接转入字符串 String string = new String(Files.readAllBytes(Paths.get(&quo ...

  2. 定时器 setInterval(‘function()’, 2000)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. Others-接口集成方式

    1. 异步通信方式可分为不互锁.半互锁和全互锁三种类型: a.不互锁方式 主模块发出请求信号后,不等待接到从模块的回答信号,而是经过一段时间.确认从模块已收到请求信号后,便撤消其请求信号:从设备接到请 ...

  4. JSTL标签库学习记录1-c

    JSTL全称为JSP Standard Tag Library,即JSP标准标签库. 导入JSTL相关的JAR包,jstl.jar standard.jar 导入jstl标签库: <%@tagl ...

  5. Optimizing graphics performance

    看U3D文档,心得:对于3D场景,使用分层次的距离裁剪,小物件分到一个层,稍远时就被裁掉,大物体分到一个层,距离很远时才裁掉,甚至不载.中物体介于二者之间. 文档如下: Good performanc ...

  6. JSP共享javabean

    JavaBean是一种可重复使用,且跨平台的软件组件.JavaBean可分为两种:一种是有用户界面(UI)的javaBean:还有一种是没有用户界面,主要负责处理事务(如数据运算,操纵数据库)的jav ...

  7. struts2的运行流程

    流程: 1:url 提交到tomcat http://localhost/s2/firstAction 2:tomcat 根据工程名 去 webapps 文件夹下找到对应工程 3:找web.xml S ...

  8. str和repr的区别(转)

    Python打印值的时候会保持该值在python代码中的状态,不是用户所希望看到的状态.而使用print打印值则不一样,print打印出来的值是用户所希望看到的状态. 例如: >>> ...

  9. 【Java】JVM(二)、Java垃圾收集算法

    一.标记-清除算法 算法主要分为两个步骤 1. 标记: 遍历所有的 GC Roots, 然后标记所有可达对象为存活对象 2. 清除: 遍历堆中所有对象,然后将没有标记的对象清除. 存在不足: 1. 效 ...

  10. Linux就业技术指导(五):Linux运维核心管理命令详解

    一,Linux核心进程管理命令 1.1 ps:查看进程 1.1.1 命令解释 功能说明 ps命令用于列出执行ps命令的那个时刻的进程快照,就像用手机给进程照了一张照片.如果想要动态地显示进程,就需要使 ...