进程间通信(IPC)之————共享内存

一. 共享内存

在系统中,两个不同的进程都会维护自己的一块地址空间,这个地址空间一般是虚拟地址,会通过mmu和页表映射到对应的物理内存中,因为不同的进程会有不同的内存空间,因此两个进程之间是无法看见彼此的数据的,而共享内存就是使两个进程看到同一块地址空间,以此来实现不同进程间的数据交互。

值得提出的是,共享内存是进程间通信方式中最高效的一种,因为是直接通过访问内存来交换数据的,省去了消息队列中数据的复制和信号量中进行P、V操作所占用的时间。

二. 共享内存中的函数

  1. 共享内存的创建与销毁

创建:

函数参数中,

key值就不用说了,是用ftok函数创建出来的,需要使用路径名和一个proj_id的整数;

size指的是需要多大的空间,在Linux中数据是按页来分的,1页也就是4K也是4096个字节,这个size的    对齐数是4096的整数倍,也就是如果你指定了4098个字节,系统就会分配4096*2的大小空间;

shmflg和消息队列及信号量中是一样的,有IPC_CREATIPC_EXCL两个选项,同时使用这两个值就会新创建出一个共享内存,若共享内存存在就会返回-1;而当IPC_CREAT单独使用时若共享内存存在就返回存在的共享内存ID,否则就会新创建;

销毁:

函数参数中,

shmid就是创建出的共享内存的ID,而cmd的选项可以是IPC_RMID,后面的buf是一个结构体指针,这里需要销毁共享内存,可以将buf设为NULL

2. 共享内存的关联与取消关联

创建出了共享内存之后,需要的就是将进程同这个共享内存关联起来以能够使用,同样,使用完了之后也需要将关联解除:

上图中,

shmat是将进程同共享内存关联起来attach,shmid是共享内存的ID,而后面的shmaddr是一个缓冲区的指    针,如果为NULL,系统会自动的选择一块合适的内存作为缓冲区,而shmflg可以是SHM_RDONLY表示    进程在共享内存中只读,而当shmflg为0时表示读写都可以,并没有只写这一选项;

可以看到shmat函数的返回值是一个void型的指针,这可以理解为在内存中开辟好了一块空间返回    的指针;

shmdt函数中参数只有一个,开辟出了内存当然也要释放了,因此shmaddr就是shmat的返回值,用来取消    关联;

栗子时间:

和前面所谈的消息队列及信号量相同,可以将共享内存中的函数封装起来:

这样可以创建两个进程shm_client.c和shm_server.c:

两个进程都与创建好的共享内存取得关联,shm_client.c向共享内存中写入数据,而shm_server.c从中取出数据打印出来,这样也就实现的进程间的通信,运行程序:

这里要说的一点就是,上一篇谈到的信号量,其实就可以和共享内存结合使用,因为当两个进程同时访问一块共享内存向中写入数据或者读取数据的时候就会产生冲突,这时可以将共享内存看做一个临界资源用信号量来作为标识,可以完成进程间的同步和互斥的问题。

《完》

时间: 2024-12-29 23:21:12

进程间通信(IPC)之————共享内存的相关文章

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

每个进程各自有不同的用户地址空间,任何一个进 程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲 区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信(IPC,InterProcess Communication) 如下图所示: 进程间通信共七种方式: 第一类:传统的unix通信机制: # 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用.进程的亲

进程间通信(IPC)之共享内存

★IPC方法包括管道(PIPE).消息队列(Message_Queue).旗语.共用内存(ShareMemory)以及套接字 (Socket).进程间通信主要包括了管道.系统IPC(包括了消息队列.信号以及共享存储).套接字(Socket). 此文将叙述共享内存的相关内容. 在此之前先来看看关于进程的内存映像的相关内容. 一.进程的内存映像(区别于可执行程序文件): 指的是内核在内存中如何存放可执行程序文件.两者的区别表现在三个方面:①可执行程序是位于硬盘上的,而内存映像位 于内存上: ②可执行

Linux IPC之共享内存C 事例

Linux IPC之共享内存 标签: linuxrandomnull工作 2011-08-25 11:52 4123人阅读 评论(0) 收藏 举报  分类: Linux(3)  读书札记(3)  版权声明:本文为博主原创文章,未经博主允许不得转载. 简介 共享内存(shared memory)是最简单的Linux进程间通信方式之一.使用共享内存,不同进程可以对同一块内存进行读写.由于所有进程对共享内存的访问就和访问自己的内存空间一样,而不需要进行额外系统调用或内核操作,同时还避免了多余的内存拷贝

linux ftok()函数 --多进程IPC之共享内存

系统建立IPC通讯(如消息队列.共享内存时)必须指定一个ID值.通常情况下,该id值通过ftok函数得到.ftok原型如下:key_t ftok( char * fname, int id ) fname就时你指定的文件名(该文件必须是存在而且可以访问的),id是子序号,虽然为int,但是只有8个比特被使用(0-255). 当成功执行的时候,一个key_t值将会被返回,否则 -1 被返回. 在一般的UNIX实现中,是将文件的索引节点号取出,前面加上子序号得到key_t的返回值.如指定文件的索引节

System V IPC 之共享内存

IPC 是进程间通信(Interprocess Communication)的缩写,通常指允许用户态进程执行系列操作的一组机制: 通过信号量与其他进程进行同步 向其他进程发送消息或者从其他进程接收消息 和其他进程共享一段内存区 System V IPC 最初是在一个名为 "Columbus Unix" 的开发版 Unix 变种中引入的,之后在 AT&T 的 System III 中采用.现在在大部分 Unix 系统 (包括 Linux) 中都可以找到. IPC 资源包含信号量.

linux进程间通信,使用共享内存方式

闲来没事给想要学习进程间使用共享内存通信的例子,共享内存的效率比消息队列.信号量都要高?为什么呢? (1)共享内存是运行在用户空间的,由应用程序控制. (2)消息队列和信号量都是把数据从一个进程用户空间复制到内核空间,然后再由内核控件复制到另外一个进程的用户空间. #include <unistd.h> #include <stdio.h> #include <string.h> #include <sys/mman.h> #include <sys/

IPC: 共享内存

################################################### 共享内存区   共享内存是IPC形式中最快的,因为共享内存不和内核进行数据交换. 通过fork派生的子进程不与父进程共享内存区.   共享内存区分为: 1.posix共享内存区 2.system V共享内存区 共享内存有两种形式: 1.匿名共享内存 2.有名共享内存 ----------------------------------------------------------- posi

进程间通信三(共享内存)

1.什么是共享内存? 共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式.不同进程之间共享的内存通常安排为同一段物理内存.进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言函数malloc分配的内存一样.而如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程.共享内存并未提供同步机制,也就是说,在第一个进程结束对共享内存的写操作之

Unix IPC之共享内存区(1)

1 共享内存区 共享内存区是可用IPC形式中最快的,只有映射和解除映射需要进入内核的系统调用,映射后对共享内存区的访问和修改不再需要系统调用(内核只要负责好页表映射和处理页面故障即可),但通常需要同步手段. 一个客户-服务器间传递文件数据的例子中,FIFO或消息队列等IPC方式通常需要4次内核-进程间的数据复制(但是Posix消息队列可使用内存映射I/O实现,就不一定4次了),每次都需要切换地址空间,开销很大:共享内存区只需要2次跨内核的数据复制. 2  mmap mmap的三个目的: 1.  

Linux IPC之共享内存

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