Linux进程通信之共享内存

来源:互联网 发布:少女前线淘宝 账号 编辑:程序博客网 时间:2024/06/08 10:57

  基于system V版本的进程间通信还有最后一种方式,那就是共享内存。
  共享内存的最大的特点就是:它是基于system V 的通信方式中速度最快的一个,这是因为共享内存不经过页表的多次转化,和多次映射,这就节省了很多资源,试问:每次通信时都要把内存上的东西映射一遍,那么这浪费的时间就不是一点半点了。他只是在创建的时候将共享内存的物理地址映射到进程的虚拟地址空间里,之后每次操作都会直接对这块空间进行操作,而不用经过繁冗的中间操作。其中,shmat函数很明显的证明了这点,这个之后我们谈。
  对于共享内存的映射模型,请看图:
  这里写图片描述
  红色箭头为正常的映射关系,黑色箭头为共享内存的映射关系。
  所以,基于这个关系,我们就可以实现一个server–>client的基于共享内存的通信方式了。
  需要用到的函数:
  

       #include <sys/ipc.h>       #include <sys/shm.h>       int shmget(key_t key, size_t size, int shmflg);

  key不解释,size时申请的共享内存的大小,需要注意的是,共享内存的基本单位是页表,每个页表的大小为4k,即4096byte。shmflg时创建共享内存的方式,IPC_CREAT|IPC_EXCL,这个也不解释,还有权限也可以一并放在shmflg中传入。
  

       #include <sys/types.h>       #include <sys/shm.h>       void *shmat(int shmid, const void *shmaddr, int shmflg);       int shmdt(const void *shmaddr);

  shmat返回创建的共享内存的地址,我们可以直接往这个地址里面写入,则会直接写入到共享内存中。
  

       #include <sys/types.h>       #include <sys/shm.h>       int shmdt(const void *shmaddr);

  可以将shmdt理解为:与shmat函数相反,是用来断开与共享内存附加点的地址,禁止本进程访问此片共享内存
  

       #include <sys/ipc.h>       #include <sys/shm.h>       int shmctl(int shmid, int cmd, struct shmid_ds *buf);

  这个函数不解释。
  看代码和结果:
  

//comm.h#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <sys/ipc.h>#include <stdlib.h>#include <string.h>#define PATH_NAME "."#define PROFECT_ID 49#define SIZE 4*1024int creatshm(){    key_t key = ftok(PATH_NAME,PROFECT_ID);    int shmid =  shmget(key,SIZE,IPC_CREAT|IPC_EXCL|0666);    if(shmid<0)    {        perror("shmget");        exit(1);    }    return shmid;}int shmidget(){    key_t key = ftok(PATH_NAME,PROFECT_ID);    int shmid =  shmget(key,SIZE,IPC_CREAT|0666);    if(shmid<0)    {        perror("shmget");        exit(2);    }    return shmid;}char* at_shm(int shmid){    return (char*)shmat(shmid,NULL,0);}int dt_shm(char* addr){    int ret =shmdt(addr);}int destroyshm(int shmid){    int ret = shmctl(shmid,IPC_RMID,NULL);    if(ret<0)    {        perror("shmctl");        exit(3);    }    return ret;}//server.c#include "comm.h"int main(){    int shmid=creatshm();    printf("server shmid:%d\n",shmid);    char* buff=NULL;    while(1)    {        buff=at_shm(shmid);        ssize_t s=read(0,buff,1024);        buff[s]=0;        if(strcmp(buff,"end")==0)        {            destroyshm(shmid);            return 0;        }        dt_shm(buff);    }    return 0;}//client.c#include "comm.h"int main(){    int shmid=shmidget();    printf("client shmid: %d\n",shmid);    char* buff=NULL;    while(1)    {        buff=at_shm(shmid);        if(strlen(buff)!=0)            printf("server--># %s\n",buff);        sleep(5);        dt_shm(buff);    }    return 0;}

server端窗口:
这里写图片描述
client端窗口:
这里写图片描述

---------------------------------------------------------------

  总结一下共享内存的优点:
  1、是所有进程通信间最快的方法;
  2、不提供互斥与同步机制,需自己使用信号量实现;
  3、共享内存的生命周期“随内核”;
  4、共享内存使用映射方法使多个进程看到同一块数据块。

关于system v IPC进程间通信的特点可以参考下方链接:
http://blog.csdn.net/smile_1991_zheng/article/details/19020249

原创粉丝点击