热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

linuxipc——sharedmemory

1、概念共享内存:共享内存是进程间通信中最简单的方式之一。共享内存允许两个或更多进程访问同一块内存,就如同malloc()函数向不同进程返回了指向同一个

1、概念

共享内存:共享内存是进程间通信中最简单的方式之一。共享内存允许两个或更多进程访问同一块内存,就如同 malloc() 函数向不同进程返回了指向同一个物理内存区域的指针。当一个进程改变了这块地址中的内容的时候,其它进程都会察觉到这个更改。

2、用途

. 共享内存允许两个或多个进程共享一给定的存储区,因为数据不需要来回复制,所以是最快的一种进程间通信机制。共享内存可以通过mmap()映射普通文件(特殊情况下还可以采用匿名映射)机制实现,也可以通过系统V共享内存机制实现。应用接口和原理很简单,内部机制复杂。为了实现更安全通信,往往还与信号灯等同步机制共同使用

  共享内存涉及到了存储管理以及文件系统等方面的知识,深入理解其内部机制有一定的难度,关键还要紧紧抓住内核使用的重要数据结构。系统V共享内存是以文件的形式组织在特殊文件系统shm中的。通过shmget可以创建或获得共享内存的标识符。取得共享内存标识符后,要通过shmat将这个内存区映射到本进程的虚拟地址空间

3、特点

共享内存。顾名思义,这种通信方式允许多个进程共享同一块物理内存空间来实现进程之间的信息交换,其特点是没有中间环节,直接将共享的内存页面通过附接,映射到相互通信的进程各自的虚拟地址空间中,从而使多个进程可以直接访问同一个物理内存页面,如同访问自己的私有空间一样(但实质上不是私有的而是共享的)。因此这种进程间通信方式是在同一个计算机系统中的诸进程间实现通信的最快捷的方法,而它的局限性也在于此,即共享内存的诸进程必须共处同一个计算机系统,有物理内存可以共享才行。

4、用法:

发送进程:
1.使用系统调用函数shmget()创建或者获取指定key值的共享内存;
2.使用系统调用函数shmat(),将该共享内存附接到自己的虚拟地址空间;
3.将需要发送的信息写入共享内存,方法有以下几种:
①.每条信息都以追加的方式写入,可以使用C语言提供的字符串追加函数strcat(viraddr, buffer),该函数的功能是将buffer中的字符串追加到由viraddr附接的共享存储区的尾部。其中,viraddr是请求得到的共享内存的地址,buffer是用户进程中请求的用来存放信息的字符缓冲区。
②.每条信息都以覆盖的方式写入,可以使用strcpy(viraddr,buffer)函数将buffer中的字符串复制到viraddr指向的共享内存中,则该共享内存中就只有当前复制进来的信息,以前复制的信息被覆盖了。
③.共享内存定义为数值型变量,则可以将*viraddr作为数值型变量对其进行操作。例如将其赋值为0可以使用:*viradd=0。
④.共享内存定义为数值型数组,则可以将viraddr[i]作为下标变量使用。例如将其赋值为0可以使用: viradd[i]=0。
4.使用系统调用函数shmdt(),断开共享内存。

 

接收进程:
    1.  用系统调用函数shmget();创建或者获取指定key值的共享内存;
    2.  用系统调用函数shmat();将该共享内存附接到自己的程序空间;
    3.将共享内存中的信息输出;或取出存放到其它数据块中;
    4.使用系统调用函数shmdt();断开共享内存。
    5.如果不再使用共享内存时,使用系统调用函数shmctl()将其撤消,格式为:shmctl(shmid,IPC_RMID,0);

获得一个共享存储标识符
 #include
 #include
 int shmget(key_t key, size_t size,intshmflg);
 功能:创建或打开一块共享内存区
 参数:
     key:IPC键值
     size:该共享存储段的长度(字节)
     shmflg:用来标识函数的行为

参数:
shmflg:用来标识函数的行为
 IPC_CREAT:如果不存在就创建
 IPC_EXCL:如果已经存在则返回失败
 IPC_NOWAIT:调用进程会立即返回。若发生错误则返回-1。
SHM_R:可读
SHM_W:可写
返回值:
成功:返回共享内存标识符。
失败:返回-1。

 

共享内存映射(attach)
 #include
 #include
 void *shmat(int shmid, const void *shmaddr,
       int shmflg);
 功能:
     将一个共享内存段映射到调用进程的数据段中。
 参数:
     shmid:共享内存标识符。
     shmaddr:共享内存映射地址(若为NULL则由系      统自动指定),推荐使用NULL。

参数:
 shmflg:共享内存段的访问权限和映射条件
0:共享内存具有可读可写权限。
SHM_RDONLY:只读。
SHM_RND:(shmaddr非空时才有效)
    没有指定SHM_RND则此段连接到shmaddr所指定的地址上(shmaddr必需页对齐)。
    指定了SHM_RND则此段连接到shmaddr- shmaddr%SHMLAB 所表示的地址上。
返回值:
成功:返回共享内存段首地址
失败:返回 -1

 

解除共享内存映射(detach)
 #include
 #include
 int shmdt(const void *shmaddr);
 功能:
       将共享内存和当前进程分离(仅仅是断开联系并不删除共享内存)。
 参数:
shmaddr:共享内存映射地址。
 返回值:
成功返回 0,失败返回 -1。

 

#include
 #include
 int shmctl(int shmid, int cmd,
       struct shmid_ds *buf);
 功能:共享内存空间的控制。
 参数:
shmid:共享内存标识符。
cmd:函数功能的控制。
buf:shmid_ds数据类型的地址,用来存放或更改消息队列的属性。

参数:
cmd:函数功能的控制
IPC_RMID:删除。
IPC_SET:设置shmid_ds参数。
IPC_STAT:保存shmid_ds参数。
SHM_LOCK:锁定共享内存段(超级用户)。
SHM_UNLOCK:解锁共享内存段。
返回值:
     成功返回 0,失败返回 -1。

5、案例

读:

#include
#include
#include
#include
#include
#include
#include

#define BUFSZ 2048

int main(int argc, char *argv[])
{
 int shmid;
 int ret;
 key_t key;
 char *shmadd;
 
 key = ftok(".", 2012);
 if(key==-1)
 {
  perror("ftok");
 }
 system("ipcs -m");
 /*打开共享内存*/
 shmid = shmget(key, BUFSZ, SHM_R|SHM_W); 
 if(shmid <0)
 {
  perror("shmget");
  exit(-1);
 }
 /*映射*/
 shmadd &#61; shmat(shmid, NULL, 0);
 if(shmadd <0)
 {
  perror("shmat");
  exit(-1);
 }
 /*读共享内存区数据*/
 printf("copy data from shared-memory\n");
 printf("data &#61; [%s]\n", shmadd);
 /*分离共享内存和当前进程*/
 ret &#61; shmdt(shmadd);
 if(ret <0)
 {
  perror("shmdt");
  exit(1);
 }
 else
 {
  printf("deleted shared-memory\n");
 }
 /*删除共享内存*/
 shmctl(shmid, IPC_RMID, NULL);
 system("ipcs -m");
 return 0;
}

写&#xff1a;

#include
#include
#include
#include
#include
#include
#include

#define BUFSZ 2048

int main(int argc, char *argv[])
{
 int shmid;
 int ret;
 key_t key;
 char *shmadd;
 
 key &#61; ftok(".", 2012);
 if(key &#61;&#61; -1)
 {
  perror("ftok");
 }
 /*创建共享内存*/
 shmid &#61; shmget(key, BUFSZ, SHM_R|SHM_W|IPC_CREAT); 
 if(shmid <0)
 {
  perror("shmget");
  exit(-1);
 }
 /*映射*/
 shmadd &#61; shmat(shmid, NULL, 0);
 if(shmadd <0)
 {
  perror("shmat");
  _exit(-1);
 }
 /*拷贝数据至共享内存区*/
 printf("copy data to shared-memory\n");
 bzero(shmadd, BUFSZ);
 strcpy(shmadd, "data in shared memory\n");
 return 0;
}

 

转:https://www.cnblogs.com/kunyashaw/archive/2013/06/05/3119406.html



推荐阅读
  • 在高并发需求的C++项目中,我们最初选择了JsonCpp进行JSON解析和序列化。然而,在处理大数据量时,JsonCpp频繁抛出异常,尤其是在多线程环境下问题更为突出。通过分析发现,旧版本的JsonCpp存在多线程安全性和性能瓶颈。经过评估,我们最终选择了RapidJSON作为替代方案,并实现了显著的性能提升。 ... [详细]
  • Linux环境下进程间通信:深入解析信号机制
    本文详细探讨了Linux系统中信号的生命周期,从信号生成到处理函数执行完毕的全过程,并介绍了信号编程中的注意事项和常见应用实例。通过分析信号在进程中的注册、注销及处理过程,帮助读者理解如何高效利用信号进行进程间通信。 ... [详细]
  • 主调|大侠_重温C++ ... [详细]
  • 本文深入探讨了MySQL中常见的面试问题,包括事务隔离级别、存储引擎选择、索引结构及优化等关键知识点。通过详细解析,帮助读者在面对BAT等大厂面试时更加从容。 ... [详细]
  • 本文详细介绍了Java中实现异步调用的多种方式,包括线程创建、Future接口、CompletableFuture类以及Spring框架的@Async注解。通过代码示例和深入解析,帮助读者理解并掌握这些技术。 ... [详细]
  • 深入剖析JVM垃圾回收机制
    本文详细探讨了Java虚拟机(JVM)中的垃圾回收机制,包括其意义、对象判定方法、引用类型、常见垃圾收集算法以及各种垃圾收集器的特点和工作原理。通过理解这些内容,开发人员可以更好地优化内存管理和程序性能。 ... [详细]
  • 本文深入探讨了UNIX/Linux系统中的进程间通信(IPC)机制,包括消息传递、同步和共享内存等。详细介绍了管道(Pipe)、有名管道(FIFO)、Posix和System V消息队列、互斥锁与条件变量、读写锁、信号量以及共享内存的使用方法和应用场景。 ... [详细]
  • KMP算法是一种高效的字符串模式匹配算法,能够在不进行回溯的情况下完成匹配,其时间复杂度为O(m+n),其中m和n分别为文本串和模式串的长度。本文将详细介绍KMP算法的工作原理,并提供C语言实现。 ... [详细]
  • 本文详细探讨了Java命令行参数的概念、使用方法及在实际编程中的应用,包括如何通过命令行传递参数给Java程序,以及如何在Java程序中解析这些参数。 ... [详细]
  • Linux环境下C语言实现定时向文件写入当前时间
    本文介绍如何在Linux系统中使用C语言编程,实现在每秒钟向指定文件中写入当前时间戳。通过此示例,读者可以了解基本的文件操作、时间处理以及循环控制。 ... [详细]
  • 深入理解Java多线程并发处理:基础与实践
    本文探讨了Java中的多线程并发处理机制,从基本概念到实际应用,帮助读者全面理解并掌握多线程编程技巧。通过实例解析和理论阐述,确保初学者也能轻松入门。 ... [详细]
  • 本文探讨了如何利用HTML5和JavaScript在浏览器中进行本地文件的读取和写入操作,并介绍了获取本地文件路径的方法。HTML5提供了一系列API,使得这些操作变得更加简便和安全。 ... [详细]
  • 本文深入探讨了 Delphi 中类对象成员的核心概念,包括 System 单元的基础知识、TObject 类的定义及其方法、TClass 的作用以及对象的消息处理机制。文章不仅解释了这些概念的基本原理,还提供了丰富的补充和专业解答,帮助读者全面理解 Delphi 的面向对象编程。 ... [详细]
  • 1、字符型常量字符型常量指单个字符,是用一对单引号及其所括起来的字符表示。例如:‘A’、‘a’、‘0’、’$‘等都是字符型常量。C语言的字符使用的就是 ... [详细]
  • NFS(Network File System)即网络文件系统,是一种分布式文件系统协议,主要用于Unix和类Unix系统之间的文件共享。本文详细介绍NFS的配置文件/etc/exports和相关服务配置,帮助读者理解如何在Linux环境中配置NFS客户端。 ... [详细]
author-avatar
吴由兴_834
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有