linux 进程间通信(IPC)包括3种机制:消息队列、信号量、共享内存。消息队列和信号量均是内核空间的系统对象,经由它们
的数据需要在内核和用户空间进行额外的数据拷贝;而共享内存和访问它的所有应用程序均同处于用户空间,应用进程可以通过地址
映射的方式直接读写内存,从而获得非常高的通信效率。在GNU/Linux中所有的进程都有唯一的虚拟地址空间,而共享内存应用编程
接口API允许一个进程使用公共内存区段。 如果使用消息队列进行通信,那么一个进程要向队列中写入消息,这要引起从用户地址空
间向内核地址空间的一次复制,同样一个进程进行消息读取时也要进行一次复制,而共享内存的优点是完全省去了这些操作。两个不
同进程A、B共享内存的意思是,同一块物理内存被映射到进程A、B各自的进程地址空间。进程A可以即时看到进程B对共享内存中数
据的更新,反之亦然,因此通过共享内存映射到进程的虚拟地址空间,进程对其可以直接访问,避免了数据的复制过程。由于多个进程
共享同一块内存区域,必然需要某种同步机制,互斥锁和信号量
共享内存区的相关操作:
使用共享内存的流程:
1.进程必须首先分配它。
2.随后需要访问这个共享内存块的每一个进程都必须将这个共享内存绑定到自己的地址空间中。
3.当完成通信之后,所有进程都将脱离共享内存,并且由一个进程释放该共享内存块。
#include <sys/ipc.h>
#include <sys/shm.h>
/*
创建一个新的内存共享区或者访问一个已经存在的共享内存区
返回共享内存区标识符
*/
int shmget(key_t key, size_t size, int shmflg);
/*
创建或打开一个共享内存区后,调用shmat把它连接到调用进程的地址空间
*/
void *shmat(int shmid, const void *shmaddr,int shmflg);
/*
当一个进程完成某个共享内存区的使用时,调用shmdt断开这个内存区
*/
int shmdt(const void *shmaddr);
/*
对内存区进行多种操作
cmd取值:
IPC_RMID:从系统中删除由shmid标识的共享内存区并拆除它
IPC_SET:给指定的共享内存区设置其shmid_ds结果成员
IPC_STAT:通过buff参数向调用者返回所指定共享内存区当前的shmid_ds结构
*/
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
#include<sys/types>
#include<sys/ipc.h>
#include<sys/shm.h>
int shmget(key_t key, size_t size, int shmflg );
参数:
key:ftok返回值或者IPC_PRIVATE
size:共享内存区大小( 字节为单位,if访问一个已经存在的,那么就是0 )
oflag:权限的组合
shmget()函数用于创建一个新的共享内存段,或者访问一个现有的共享内存段,它与消息队列以及信号集合对应的函数十分相似.如
果shmflg只为IPC_CREAT,shmget()或者将返回新创建的内存段标识符,或者返回早已存在于内核中的具有的相同关键字值(key)
的内存段的标识符;如果其同时为IPC_CREAT和IPC_EXCL,则如果该内存段不存在就创建一个新的内存段,如果早已存在,则此时
调用失败,并将返回-1.
#include<sys/types>
#include<sys/ipc.h>
#include<sys/shm.h>
void *shmat(int shmid,const void *shmaddr,int shmflg);
int shmdt(const void *shmaddr);
函数shmat()用来获取共享内存的地址,获取成功后,就可以像使用普通内存一样对其进行读写操作。
#include<sys/types>
#include<sys/ipc.h>
#include<sys/shm.h>
int shmdt(const void *shmaddr);
当某一个进程不再需要一个共享内存段时,它必须调用这个函数来断开与该内存段的连接
#include<sys/types>
#include<sys/ipc.h>
#include<sys/shm.h>
int shmctl(int shmid,int cmd,struct shmid_ds *buf);
共享内存控制函数,它的使用类似ioctl()的方式对共享内存进行操作:向共享内存的句柄发送命令,来完成某种命令
对于每个共享的内存区,内核维护如下的信息结构,定义在<sys/shm.h>头文件中。
1 struct shmid_ds {
2 struct ipc_perm shm_perm; /* operation perms */
3 int shm_segsz; /* size of segment (bytes) */
4 time_t shm_atime; /* last attach time */
5 time_t shm_dtime; /* last detach time */
6 time_t shm_ctime; /* last change time */
7 unsigned short shm_cpid; /* pid of creator */
8 unsigned short shm_lpid; /* pid of last operator */
9 short shm_nattch; /* no. of current attaches */
10 /* the following are private */
11 unsigned short shm_npages; /* size of segment (pages) */
12 unsigned long *shm_pages; /* array of ptrs to frames -> SHMMAX */
13 struct vm_area_struct *attaches; /* descriptors for attaches */
14 };
这里有点要注意,当我们调用shmdt()来删除共享内存段时,只是断开该进程与这个内存段的连接,而此时内核不一定就删除内存段,
结合上述,在成功完成了断开连接操作后,相关的shmid_ds结构的shm_nattch成员的值将减去1,如果这个值减到0,则内核将真正
删除该内存段。
linux编程之共享内存的更多相关文章
-
Linux信号量同步共享内存实验.
Linux信号量同步共享内存实验. Linux信号量同步共享内存实验. 简述 程序流程 信号量和共享内存的系统函数 信号量系统函数及接口 共享内存系统函数及接口 写程序 读程序 简述 本文主要内容是自 ...
-
Linux环境进程间通信: 共享内存
Linux环境进程间通信: 共享内存 第一部分 共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式.两个不同进程A.B共享内存的意思是,同一块物理内存被映射到进程A.B各自的进程地址空间.进 ...
-
Linux IPC之共享内存C 事例
Linux IPC之共享内存 标签: linuxrandomnull工作 2011-08-25 11:52 4123人阅读 评论(0) 收藏 举报 分类: Linux(3) 读书札记(3) 版权 ...
-
Linux进程间通信—使用共享内存
Linux进程间通信-使用共享内存 转自: https://blog.csdn.net/ljianhui/article/details/10253345 下面将讲解进程间通信的另一种方式,使用共享内 ...
-
Linux环境编程之共享内存区(一):共享内存区简单介绍
共享内存区是可用IPC形式中最快的.一旦内存区映射到共享它的进程的地址空间,进程间数据的传递就不再涉及内核.然而往该共享内存区存放信息或从中取走信息的进程间通常须要某种形式的同步.不再涉及内核是指:进 ...
-
linux网络编程之共享内存介绍
今天是个好日子,洋人之节乃全球同庆,圣诞一来感觉就要过年了,不过今晚心情有点打折扣,给心爱的人打电话没有打通,本想在平安夜送上快乐的祝福给她,糟糕的心情让自己好像泄了气的皮球一样,无精打彩,心情灰暗, ...
-
Linux IPC POSIX 共享内存
模型 #include <unistd.h> //for fstat() #include <sys/types.h> //for fstat() #include <s ...
-
Linux进程间通信之共享内存
一,共享内存 内核管理一片物理内存,允许不同的进程同时映射,多个进程可以映射同一块内存,被多个进程同时映射的物理内存,即共享内存. 映射物理内存叫挂接,用完以后解除映射叫脱接. 1,共享内存的特点 ...
-
Linux进程间通信——使用共享内存
一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式.不同进程之间共享的内存通常安排为同一段物理内存. ...
随机推荐
-
MD5加密操作
MD5加密操作:MD5加密算法原理MD5的全称是Message-Digest Algorithm 5(信息-摘要算法),它的作用是让大容量信息在用数字签名软件签署私人密匙前被"压缩" ...
-
Manthan, Codefest 16
暴力 A - Ebony and Ivory import java.util.*; import java.io.*; public class Main { public static void ...
-
sql中with as的用法练习
在工作中经常看到有人使用with as,查询很顺畅,也很快,很好奇,在网上也有不少资料,看了大神的文章,也练习一下. 首先给出两位位大神文章的链接,介绍十分详细:http://www.cnblogs. ...
-
HDU 1077Catching Fish(简单计算几何)
Catching Fish Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) T ...
-
nmap命令-----基础用法
系统漏洞扫描之王-nmap NMap,也就是Network Mapper,是Linux下的网络扫描和嗅探工具包. 其基本功能有三个: (1)是扫描主机端口,嗅探所提供的网络服务 (2)是探测一 ...
-
在centos中php 在连接mysql的时候,出现Can&#39;t connect to MySQL server on &#39;XXX&#39; (13)
原文连接:http://hi.baidu.com/zwfec/item/64ef5ed9bf1cb3feca0c397c 红色的是命令 SQLSTATE[HY000] [2003] Can't con ...
-
COCI2014-2015CONTEST#7——POLICE
http://www.hsin.hr/coci/archive/2014_2015/contest7_tasks.pdf [题目描述] 有N个书架,每个书架可以容纳M本书.给出了若干本书,每本书有一个 ...
-
JavaScript sort()方法比较器
当我们想把一个由数字组成的数组进行简单的排序时,可能会想到sort()方法: var arr = [2 , 3, -1, -107, -14, 1]; console.log(arr.sort()) ...
-
XML配置文件中写版本号.xsd和不写版本号的区别
如果写版本号则默认从网上下载并指定最新版本,如果不写版本号则默认从本地下载并使用最新版本.
-
Elasticsearch集群优化
版本配置: ES版本:6.2.4 OS内存64G. 一.参数配置: ES jvm内存31G. vi /etc/sysctl.conf vm.swappiness = 1 elasticsearch.y ...