详解共享内存以及所有进程间通信的特点

来源:互联网 发布:18天内减少体重 知乎 编辑:程序博客网 时间:2024/06/16 08:53

一、什么是共享内存?

共享内存:使得多个进程可以访问同一块内存空间

共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常安排为同一段物理内存。进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址。

二、共享内存的特点

(1)、共享内存是以传输数据为目的
(2)、共享内存无同步无互斥
(3)、共享内存是所有进程间通信速度最快的。
(4)、共享内存的生命周期随内核

三、共享内存的优缺点

1、优点:使用共享内存进行进程间的通信非常方便,而且函数的接口也简单,数据的共享使进程间的数据不用传送,而是直接访问内存,加快了程序的效率。同时,它也不像匿名管道那样要求通信的进程有一定的父子关系。
2、缺点:共享内存没有提供同步的机制,这使得我们在使用共享内存进行进程间通信时,往往要借助其他的手段来进行进程间的同步工作。

四、实现共享内存

在学习共享内存的代码前我们先来看几个关于共享内存的函数。

1、创建共享内存——shmget函数

函数原型为:

      int shmget(key_t key,size_t size,int shmflg);

key:让两个不同进程可以访问到同一资源。
size:表示共享内存的大小。
shmflg:代表标志位,分别是IPC_CREAT,IPC_EXCL。IPC_CREAT单独使用时表示 若存在共享内存,打开返回,若不存在,创建之。IPC_EXCL一般不单独使用。若两个标志位同时使用表示若存在共享内存,出错返回,若不存在,则创建之。

2、销毁共享内存——shmctl函数

函数原型为:

       int shmctl(int shmid,int cmd,struct shmid_ds *buf);


shm_id:是shmget函数返回的共享内存标识符。

cmd:command是要采取的操作,它可以取下面的三个值 :

IPC_STAT:把shmid_ds结构中的数据设置为共享内存的当前关联值,即用共享内存的当前关联值覆盖shmid_ds的值。
IPC_SET:如果进程有足够的权限,就把共享内存的当前关联值设置为shmid_ds结构中给出的值
IPC_RMID:删除共享内存段


buf:是一个结构指针,它指向共享内存模式和访问权限的结构。
shmid_ds结构至少包括以下成员:

struct shmid_ds {    struct ipc_perm shm_perm;    /* Ownership and permissions */    size_t shm_segsz;   /* Size of segment (bytes) */    time_t shm_atime;   /* Last attach time */    time_t shm_dtime;   /* Last detach time */    time_t shm_ctime;   /* Last change time */    pid_t  shm_cpid;    /* PID of creator */    pid_t  shm_lpid;    /* PID of last shmat(2)/shmdt(2) */    shmatt_t shm_nattch;  /* No. of current attaches */               ... };

接下来,让我们来看看如何显示共享内存的相关代码吧!
Makefile:

   .PHONY:allall:client serverclient:client.c comm.c    gcc -o $@ $^server:server.c comm.c    gcc -o $@ $^.PHONY:cleanclean:    rm -f server client

comm.h:

#define _COMM_H_#define PATHNAME "."#define PROJ_ID 0x6666#include<stdio.h>#include <sys/ipc.h>#include <sys/shm.h>int creatShm(int size);int getShm(int size);int destoryShm(int shmid);#endif //_COMM_H_

comm.c:

#include "comm.h"static int commShm(int size,int flags){   key_t _key=ftok(PATHNAME,PROJ_ID);   if(_key<0)  {     perror("ftok");     return -1;  }  int shmid=shmget(_key,size,IPC_CREAT|IPC_EXCL);  if(shmid<0)  {     perror("shmget");      return -2;  }   return shmid;}int createShm(int size){    return commShm(size,IPC_CREAT|IPC_EXCL);}int getShm(int size) {      return commShm(size,IPC_CREAT); }int destoryShm(int shmid){   if((shmctl(shmid,IPC_RMID,NULL))!=0)   {       perror("shmctl");       return -1;   }    return 0;}

client.c:

include "comm.h"int main(){    printf("hello,bit!\n");    return 0;}

server.c :

#include "comm.h"int main(){    int shmid =createShm(4097);//创建共享内存    sleep(1);    printf("hello,ShareMemory\n");    sleep(4);    destoryShm(shmid);//销毁共享内存    return 0;}

程序的运行结果为:创建内存成功后1s后输出hello,ShareMemory然后4s后共享内存被销毁!(如图所示)
没创建共享内存前:

创建后:

这里写图片描述

这里写图片描述

4s后,共享内存被销毁。

这里写图片描述

关于共享内存我们就说到这里,接下来让我们看看关于进程间通信的相关知识吧!

五、进程间通信的特点

每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信(IPC)。

IPC的方式通常有管道(包括匿名管道和命名管道)、消息队列、信号量、共享内存等。

接下来我们来看看它们各自有什么特点!

管道:

(1)匿名管道:

它的数据只能在一个方向上流动,具有固定的读端和写端。

它只能用于具有亲缘关系的进程之间的通信(例如父子进程或者兄弟进程之间)。

它可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。

(2)命名管道(FIFO):

与匿名管道不同。FIFO可以在无关的进程之间交换数据,与无名管道不同。

FIFO有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中。

消息队列:

消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级。

消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除。

消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。

消息队列的生命周期随内核

信号量:

信号量是一个计数器。信号量用于实现进程间的互斥与同步,而不是用于存储进程间通信数据。

信号量基于操作系统的 PV 操作,程序对信号量的操作都是原子操作,保证信号量的原子性。

每次对信号量的 PV 操作不仅限于对信号量值加 1 或减 1,而且可以加减任意正整数。

支持信号量组,拥有了信号量,就可以拥有使用临界资源。

共享内存:

共享内存是最快的一种 IPC,因为进程是直接对内存进行存取。

共享内存是以传输数据为目的,故无同步与互斥。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 微信10w限额满了怎么办 微信身份证实名认证超出限额怎么办 微信信用卡消费超过当日限额怎么办 淘宝客服同意退货卖家拒绝怎么办 微信钱包充值话费不到帐怎么办 京东买的显示器过保坏了怎么办 支付宝充话费充错号码是空号怎么办 京东充话费充错了号码该怎么办 微信红包充话费不到账怎么办 支付宝充话费等待第三方发货怎么办 微信充话费显示成功但没收到怎么办 微信退款一直在退款中怎么办 文件大于100发不了微信怎么办 微信的传送文件大于100怎么办 微信钱包话费充值错误怎么办 微信转账到不了账也退不回是怎么办 求人办事微信发红包对方不收怎么办 微信上交了订金对方不退怎么办 交通事故对方伤员堵大门搂腿怎么办 电脑开机桌面文件都没了怎么办 qq飞车手游队长换了微信群怎么办 qq飞车手游登录授权失败怎么办 安装时提示安装包发现错误怎么办 苹果6p升级系统验证失败怎么办 w10开不了机无限重启怎么办 微信朋友圈里的表情图打不开怎么办 金立手机微信启动录音被拒绝怎么办 微信帐号解封后漂流瓶不能用怎么办 微信怎么在电脑上登不上去怎么办 玩旧版60级魔兽经常花屏怎么办? 我的世界手机版物品栏不见了怎么办 苹果手机掉进水里出现花屏该怎么办 球球大作战还没进去停止运行怎么办 ps3 e3硬破芯片坏了怎么办 电话打开后页面上没有东西怎么办 WPS在电脑安装后卸载不了怎么办 ps总要以管理员的身份打开怎么办 3d关的慢保存慢怎么办 无法与服务器建立可靠的连接怎么办 被抵押的房子开发商不解押怎么办 手机系统语言是英文没有中文怎么办