共享内存:

一、概念:

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

进程A可以即时看到进程B对共享内存中数据的更新,反之亦然。由于多个进程共享同一块内存区域,必然需要某种同步机制,互斥锁和信号量都可以。

采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝。

对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,

而共享内存则只拷贝两次数据[1]:

1.一次从输入文件到共享内存区,

2.另一次从共享内存区到输出文件。

实际上,进程之间在共享内存时,并不总是读写少量数据后就解除映射,有新的通信时,再重新建 立共享内存区域。而是保持共享区域,直到通信完毕为止,这样,数据内容一直保存在共享内

存中,并没有写回文件。共享内存中的内容往往是在解除映射时才写回 文件的。因此,采用共享内存的通信方式效率是非常高的。

二、相关函数:

与信号量一样,在Linux中也提供了一组函数接口用于使用共享内存,而且使用共享共存的接口还与信号量的非常相似,而且比使用信号量的接口来得简单。它们声明在头文件 sys/shm.h中。

1、shmget函数
该函数用来创建共享内存,它的原型为:
int shmget(key_t key, size_t size, int shmflg);  
1.第一个参数,与信号量的semget函数一样,程序需要提供一个参数key(非0整数),它有效地为共享内存段命名。

    shmget函数成功时返回一个与key相关的共享内存标识符(非负整数),用于后续的共享内存函数。调用失败返回-1.

    不相关的进程可以通过该函数的返回值访问同一共享内存,它代表程序可能要使用的某个资源,程序对所有共享内存的访问都是间接的,程序先通过调用shmget函数并提供一个键,再由

系统生成一个相应的共享内存标识符(shmget函数的返回值),只有shmget函数才直接使用信号量键,所有其他的信号量函数使用由semget函数返回的信号量标识符。

2.第二个参数,size以字节为单位指定需要共享的内存容量

3.第三个参数,shmflg是权限标志,它的作用与open函数的mode参数一样,如果要想在key标识的共享内存不存在时,创建它的话,可以与IPC_CREAT做或操作。

共享内存的权限标志与文件的读写权限一样,举例来说,0644,它表示允许一个进程创建的共享内存被内存创建者所拥有的进程向共享内存读取和写入数据,同时其他用户创建的进程只能读取共

享内存。

2、shmat函数
第一次创建完共享内存时,它还不能被任何进程访问,shmat函数的作用就是用来启动对该共享内存的访问,并把共享内存连接到当前进程的地址空间。它的原型如下:
void *shmat(int shm_id, const void *shm_addr, int shmflg); 
第一个参数,shm_id是由shmget函数返回的共享内存标识。

第二个参数,shm_addr指定共享内存连接到当前进程中的地址位置,通常为空,表示让系统来选择共享内存的地址。

第三个参数,shm_flg是一组标志位,通常为0。

调用成功时返回一个指向共享内存第一个字节的指针,如果调用失败返回-1.

3、shmdt函数
该函数用于将共享内存从当前进程中分离。注意,将共享内存分离并不是删除它,只是使该共享内存对当前进程不再可用。它的原型如下:
int shmdt(const void *shmaddr);  
参数shmaddr是shmat函数返回的地址指针,调用成功时返回0,失败时返回-1.

4、shmctl函数
与信号量的semctl函数一样,用来控制共享内存,它的原型如下:
int shmctl(int shm_id, int command, struct shmid_ds *buf); 
第一个参数,shm_id是shmget函数返回的共享内存标识符

第二个参数,command是要采取的操作,它可以取下面的三个值 :
    IPC_STAT:把shmid_ds结构中的数据设置为共享内存的当前关联值,即用共享内存的当前关联值覆盖shmid_ds的值。
    IPC_SET:如果进程有足够的权限,就把共享内存的当前关联值设置为shmid_ds结构中给出的值
    IPC_RMID:删除共享内存段

第三个参数,buf是一个结构指针,它指向共享内存模式和访问权限的结构。
shmid_ds结构至少包括以下成员:
struct shmid_ds
{
uid_t shm_perm.uid;
uid_t shm_perm.gid;
mode_t shm_perm.mode;
};

三、实例:


关于共享内存的实例见下面博客,已经很好了,我也就不在班门弄斧了:

赐教!

Linux下进程间通信--共享内存:最快的进程间通信方式的更多相关文章

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

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

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

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

  3. linux 下 取进程占用内存(MEM)最高的前10个进程

    # linux 下 取进程占用 cpu 最高的前10个进程ps aux|head -1;ps aux|grep -v PID|sort -rn -k +3|head # linux 下 取进程占用内存 ...

  4. Linux 下增大tomcat内存

    我的服务器的配置: # OS specific support.  $var _must_ be set to either true or false. JAVA_OPTS="-Xms10 ...

  5. (转)Linux下tomcat JVM内存设置步骤

    java.lang.OutOfMemoryError: PermGen space java.lang.OutOfMemoryError: Java heap space -------------- ...

  6. C# 进程间通信(共享内存)

    原文:C# 进程间通信(共享内存) 进程间通信的方式有很多,常用的方式有: 1.共享内存(内存映射文件,共享内存DLL). 2.命名管道和匿名管道. 3.发送消息 本文是记录共享内存的方式进行进程间通 ...

  7. Linux IPC之共享内存

    System V共享内存机制: shmget  shmat  shmdt  shmctl 原理及实现: system V IPC机制下的共享内存本质是一段特殊的内存区域,进程间需要共享的数据被放在该共 ...

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

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

  9. linux下scsi共享磁盘的简单搭建

    linux下scsi共享磁盘的简单搭建 Scsi 共享磁盘需要我先有空余的分区,或者可以在虚拟机里面添加一块磁盘,安装所需的软件我在虚拟机里面添加了一块硬盘,分了一个主分区,sdb1 1G,将这个用s ...

  10. [转帖]linux下CPU、内存、IO、网络的压力测试,硬盘读写速度测试,Linux三个系统资源监控工具

    linux下CPU.内存.IO.网络的压力测试,硬盘读写速度测试,Linux三个系统资源监控工具 https://blog.51cto.com/hao360/1587165 linux_python关 ...

随机推荐

  1. ASP.NET 后台打开新页面

    [TOC] Response.Write 这是最常见的后台打开新页面的方法. Response.Write("<script>window.open('~/FileView.as ...

  2. 【转载】 Spark性能优化:资源调优篇

    在开发完Spark作业之后,就该为作业配置合适的资源了.Spark的资源参数,基本都可以在spark-submit命令中作为参数设置.很多Spark初学者,通常不知道该设置哪些必要的参数,以及如何设置 ...

  3. 【BZOJ4916】神犇和蒟蒻(杜教筛)

    [BZOJ4916]神犇和蒟蒻(杜教筛) 题面 BZOJ 求 \[\sum_{i=1}^n\mu(i^2)\ \ 和\ \sum_{i=1}^n\phi(i^2)\] 其中\[n<=10^9\] ...

  4. hibernate 反向生成 实体类

    1,配置数据库连接 步骤. 点击    windows   -> open perspective  - >   myeclipse datebase  Exprorer 打开了dateb ...

  5. kerberos下JAVA代码操作hbase的方式(客户端方式,应用程序方式)

    (一)如果部署JAVA 代码的主机用户获取了kerberos权限情况下 假设主机名是:client su - client 登录主机后 kinit -kt /keytab的路径/client.keyt ...

  6. mycat操作MySQL第一篇:全局表

    1.安装mycat,点击bin下面startup_nowrap.bat启动 2.客户端连接mycat:server.xml里面的 <!--连接mycat用户名和密码.数据库--> < ...

  7. asp.net WebApi 使用总结

    如果想让服务端直接返回json或者xml的话,可以考虑使用webservice.wcf,或者webapi.webservice基于xml,效率较慢,wcf虽然可以返回json,但是配置繁琐.webap ...

  8. HBase新的客户端接口

    最近学习接触HBase的东西,看了<Habase in Action>,但里面关于HBase接口都是过时的接口,以下为HBase新的客户端接口: package com.n10k; imp ...

  9. Raid 配置

    清除所有外部设备 /opt/MegaRAID/MegaCli/MegaCli64 '-CfgForeign -Clear' -aAll 修改盘的jbod状态 /opt/MegaRAID/MegaCli ...

  10. 实用的Docker入门

    1 Docker概述 Docker和虚拟机一样,都拥有环境隔离的能力,但它比虚拟机更加轻量级,可以使资源更大化地得到应用.首先来看Docker的架构图: 理解其中几个概念: Client(Docker ...