共享内存的实现

共享内存可以说最有用的进程间通信方式,也是最快的IPC形式。两个不同进程A,B共享内存的意思是,同一块物理内存被映射到进程A,B各自的进程地址空间。进程A可以及时看到进程B对共享内存中数据的更新,反之亦然 。由于多个进程共享同一块内存区域,必然需要某种同步机制 ,互斥锁和信号量都可以。

采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝,对于管道和消息队列等通信方式,则需要在内核和用户空间进行4次的数据拷贝,而共享内存则只拷贝两次数据,一次从输入文件到共享内存区,另一次从共享内存区到输出文件。实际上,进程之间在共享内存时,并不总是读写少量数据后就解除映射,有新的通信时,再重新建立共享内存区域。而是保持共享区域,直到通信完毕为止,这样数据内容一直保存在共享内存中,并没有写回文件,共享内存中的内容是在解除映射时才写回文件的。因此,采用共享内存的效率是非常高的。

下面我们来写一段程序来看看共享内存的应用:

comm.c文件:

#include "comm.h"

int comm_shm_creat(int flag)

{

key_t _key=ftok(_PATH_,_PROJ_ID_);

if(_key<0)

{

perror("ftok");

return -1;

}

int shm_id=shmget(_key,_SIZE_,flag);

if(shm_id<0)

{

perror("shmget");

return -1;

}

return shm_id;

}

int shm_creat()

{

umask(0);

int flag=IPC_CREAT|IPC_EXCL|0666;

return comm_shm_creat(flag);

}

int shm_get()

{

int flag=IPC_CREAT;

return comm_shm_creat(flag);

}

int shm_destroy(int shm_id)

{

if(shmctl(shm_id,IPC_RMID,NULL)<0)

{

perror("shmctl");

return -1;

}

return 0;

}

void* at_shm(int shm_id)

{

return shmat(shm_id,NULL,0);

}

int dt_shm(void *addr)

{

return shmdt(addr);

}

shm_server.c文件:

#include "comm.h"

int main()

{

int shm_id=shm_creat();

char *start=at_shm(shm_id);

int i=0;

for(;i<_SIZE_;++i)

{

printf("%s\n",start);

sleep(1);

}

dt_shm(start);

shm_destroy(shm_id);

return 0;

}

shm_client.c文件:

#include "comm.h"

int main()

{

int shm_id=shm_get();

char *start=at_shm(shm_id);

int i=0;

for(;i<_SIZE_;++i)

{

start[i]=‘A‘;

start[i+1]=‘\0‘;

sleep(1);

}

dt_shm(start);

return 0;

}

运行结果如下:

从上图结果可以看到,他们shmget的ID相同,而且client写的内容被server接收到了,实现了进程间通信的目的。

时间: 2024-11-09 05:06:45

共享内存的实现的相关文章

php 共享内存

转:php 共享内存 共享内存主要用于进程间通信 php中的共享内存有两套扩展可以实现 1.shmop  编译时需要开启 --enable-shmop 参数 实例: $shm_key = ftok(__FILE__, 't'); /** 开辟一块共享内存 int $key , string $flags , int $mode , int $size $flags: a:访问只读内存段 c:创建一个新内存段,或者如果该内存段已存在,尝试打开它进行读写 w:可读写的内存段 n:创建一个新内存段,如

Linux --进程间通信--共享内存

一.共享内存 共享内存是最高效的通信方式,因为不需要一个进程先拷贝到内核,另一个进程在存内核中读取. 二. ipcs -m 查看共享内存 ipcrm -m 删除共享内存 三.主要函数 shmget 创建 shmctl 删除 shmat 挂接 shmdt 取消挂接 ********* man 函数名 查看***** 四.代码实现 comm.h   1 #pragma once   2 #include<stdio.h>   3 #include<stdlib.h>   4 #incl

linux共享内存之mmap

这应该可以算得上是IPC的一种,虽然效率可能并没有其它IPC方式高. 看到map很容易联想到映射.的确,mmap就是一种映射方式,将打开的文件和一段连续的内存做映射.使得对内存进行操作即可以实现对文件的读写,反过来,也就是说,可以通过这种方式来达到进程通信. mmap系列涉及三个函数. void * mmap(void *buf, size_t len, int prot, int flag, int fd, off_t offset); 此函数建立一个共享内存,prot即为权限,可选值有PRO

linux 共享内存实现

说起共享内存,一般来说会让人想起下面一些方法:1.多线程.线程之间的内存都是共享的.更确切的说,属于同一进程的线程使用的是同一个地址空间,而不是在不同地址空间之间进行内存共享:2.父子进程间的内存共享.父进程以MAP_SHARED|MAP_ANONYMOUS选项mmap一块匿名内存,fork之后,其子孙进程之间就能共享这块内存.这种共享内存由于受到进程父子关系的限制,一般较少使用:3.mmap文件.多个进程mmap到同一个文件,实际上就是大家在共享文件page cache中的内存.不过文件牵涉到

Linux 进程间共享内存 SYSTEMV

#include <sys/ipc.h> #include <sys/shm.h> int shmget(key_t key, int size, int shmflag) key取值为IPC_PRIVATE时,shmflag应为IPC_CREAT,则新建共享内存key取值不为IPC_PRIVATE则应为已创建的key值,shmflag不应包含IPC_CREAT和IPC_EXCL,且大小小于等于原共享内存大小成功则返回共享内存id,失败返回-1 void *shmat(int sh

(转载)linux下的僵尸进程处理SIGCHLD信号Linux环境进程间通信(五): 共享内存(下)

Linux环境进程间通信(五): 共享内存(下) 在共享内存(上)中,主要围绕着系统调用mmap()进行讨论的,本部分将讨论系统V共享内存,并通过实验结果对比来阐述两者的异同.系统V共享内存指的是把所有共享数据放在共享内存区域(IPC shared memory region),任何想要访问该数据的进程都必须在本进程的地址空间新增一块内存区域,用来映射存放共享数据的物理内存页面. 系统调用mmap()通过映射一个普通文件实现共享内存.系统V则是通过映射特殊文件系统shm中的文件实现进程间的共享内

撸代码--linux进程通信(基于共享内存)

1.实现亲缘关系进程的通信,父写子读 思路分析:1)首先我们须要创建一个共享内存. 2)父子进程的创建要用到fork函数.fork函数创建后,两个进程分别独立的执行. 3)父进程完毕写的内容.同一时候要保证子进程退出后,在删除共享内存. 4)子进程完毕读的内容. 效果展示:                 代码展示:           #include <string.h> #include <unistd.h> #include <sys/types.h> #inc

PHP 共享内存使用与信号控制

共享内存 共享内存的使用主要是为了能够在同一台机器不同的进程中共享一些数据,比如在多个 php-fpm 进程中共享当前进程的使用情况.这种通信也称为进程间通信(Inter-Process Communication),简称 IPC. PHP 内置的 shmop 扩展 (Shared Memory Operations) 提供了一系列共享内存操作的函数(可能是用的人不多吧,这一块儿的文档还没有中文翻译).在 Linux 上,这些函数直接是通过调用 shm* 系列的函数实现,而 Winodows 上

信号量学习 &amp; 共享内存同步

刚刚这篇文章学习了共享内存:http://www.cnblogs.com/charlesblc/p/6142139.html 里面也提到了共享内存,自己不进行同步,需要其他手段比如信号量来进行.那么现在就学习信号量咯. 共享内存实际编程中, 应该使用信号量, 或通过传递消息(使用管道或IPC消息), 或生成信号 的方法来提供读写之间的更有效的同步机制. 方法一.利用POSIX有名信号灯实现共享内存的同步 方法二.利用POSIX无名信号灯实现共享内存的同步 方法三.利用System V的信号灯实现

由共享内存引发的思考

1.共享内存段被映射进进程空间之后,存在于进程空间的什么位置?共享内存段最大限制是多少? 存在于进程数据段,最大限制是0x2000000Byte 将一块内存映射到两个或者多个进程地址空间.通过指针访问该共享内存区.一般通过mmap将文件映射到进程地址共享区. Linux对共享内存的实现,在2.6采用了内存映射技术.对于内存共享,主要集中在三个内核函数,他们是do_shmat,sys_shmat和sys_shmdt.其中,sys_shmat调用了do_shmat最终实现了共享内存的attach.s