IPC之共享内存

在多进程程序中(vfork创建的多进程除外),即使是全局变量也无法共享,各个进程都会保存局部变量或全局变量的副本,供自己使用。

共享内存将文件地址映射到内存中即可让多个进程共享内存中的数据。

内存映射API

#include<sys/mman.h>
void *mmp(void *addr, size_t len, int prot, int flags, int fd, off_t offset);//调用成功则返回被映射区的起始地址,出错则为MAP_FAILED

addr可以指定描述符fd应被映射到的进程内空间的起始地址。它通常被指定为一个空指针,这样告诉内核自己去选择起始地址。无论那种情况,该函数的返回值都是描述符fd所映射到内存区的起始地址。

使用例程

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/mman.h>
#include<fcntl.h>
#include<semaphore.h>

#define SEM_NAME	"mysem"
int main(int argc, char *argv[])
{
	int	fd, i, nloop, zero = 0;
	int 	*ptr;
	sem_t	*mutex;

	if(argc != 3)
		printf("usage :incr2 <pathname> <#loops>\n");
	nloop = atoi(argv[2]);

	fd = open(argv[1], O_RDWR|O_CREAT, 0664);
	write(fd, &zero, sizeof(int));
	ptr = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
	close(fd);

	mutex = sem_open(SEM_NAME, O_CREAT|O_EXCL, 0664, 1);
	sem_unlink(SEM_NAME);

	setbuf(stdout, NULL);
	if(fork() == 0)
	{
		for(i=0; i<nloop; ++i)
		{
			sem_wait(mutex);//对信号量mutex减一,是一个阻塞的原子操作
			printf("child: %d\n", (*ptr)++);
			sem_post(mutex);//对信号量mutex加一,是一个阻塞的原子操作
		}
		exit(0);
	}
	for(i=0; i<nloop; ++i)
	{
		sem_wait(mutex);
		printf("parent %d\n", (*ptr)++);
		sem_post(mutex);
	}
	exit(0);
}

sem_unlink功能简介

当进程创建一个有名信号量,会在/dev/shm下生成一个sem.xxx的文件,所有打开该信号量的进程(包括创建它的进程)都会增加该文件的引用计数,并且这个计数由内核管理。当调用sem_unlink时,/dev/shm下的sem.xxx文件会马上被删除,但是信号量本身并没有被删除,所有已打开该信号量的进程仍能正常使用它。直到所有打开该信号量的进程关闭该信号量后,内核才真正删除信号量。

运行一下

运行效果可以看出,进程在交替运行时,自增时使用的是一个变量。

原文地址:https://www.cnblogs.com/area-h-p/p/11929241.html

时间: 2024-10-08 20:50:30

IPC之共享内存的相关文章

Linux IPC之共享内存C 事例

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

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

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

IPC: 共享内存

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

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

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

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的返回值.如指定文件的索引节

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

System V IPC 之共享内存

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

Linux IPC 共享内存用法

Linux IPC 常见的方式 写 Linux Server 端程序,必然会涉及到进程间通信 IPC. 通信必然伴随着同步机制,下面是一些常见的通信与同步机制: 进程间通信:匿名管道,命名管道,消息队列,共享内存,Domain Socket, 本机 TCP Socket,文件 进程间同步:信号,信号量 线程间同步:条件变量,互斥量,读写锁,自旋锁,Barrier. 对于大部分的业务场景,本机 TCP Socket 足以,现在Linux 也对本机 TCP Socket做了很好的优化.而且如果以后需