Linux下进程间共享内存编码方式入门

来源:互联网 发布:人工智能专业课程 编辑:程序博客网 时间:2024/04/29 17:19

相关参考:百度百科

同一台电脑上一些相关进程间的通讯方式有很多种,管道、共享文件,数据库等等。
今天在这里介绍一个(进程间)共享内存的方式。这个方法在linux和windows上都是得到os支持的。他会比数据库或者共享文件等更节约资源同时代码比管道等方式更统一(不同os间)。共享内存并发性比前几种方式略优。

在linux上支持,需要调用到基本c/c++库的ipc、shm库。ipc包含ftok函数定义,用于Linux系统建立IPC通讯 (消息队列、信号量和共享内存) 时必须指定一个ID值。后者是共享内存函数的头文件库。

共享内存的相关函数一共四个,熟悉这四个函数(详见参考)即可写出不错的共享内存的程序。不过本文在这里不做流水帐,诸位看百度百科即可,本文旨在给各位点出使用这些函数时的要点及补充百度百科中缺漏的较重要知识。

首先注意到,所有的共享内存函数的error文字描述,都是写入到error全局变量中的,想要输出这个错误描述,调用perror函数,该函数的形参(一个字符串),会输出在error信息之前。

具体到四个函数,我们来一个一个详细说明,

首先是shmctl,这个函数先介绍还真是不合理,因为它的功能虽然包含获取及修改共享内存当前状态,但最主要的功能还是:删除共享内存!请记得,后面那个shmdt只是断开某个进程与共享内存之间的关联,而只有这个才是从系统中彻底删除共享内存!同时可以注意到,该函数的读取及修改状态需要用到结构题 shmid_ds,这个结构题的具体定义如下:

struct shmid_ds {    struct ipc_perm shm_perm;   /* operation perms */    int shm_segsz;              /* size of segment (bytes) */    __kernel_time_t shm_atime;  /* last attach time */    __kernel_time_t shm_dtime;  /* last detach time */    __kernel_time_t shm_ctime;  /* last change time */    __kernel_ipc_pid_t shm_cpid; /* pid of creator */    __kernel_ipc_pid_t shm_lpid; /* pid of last operator */    unsigned short shm_nattch;   /* no. of current attaches */    unsigned short shm_unused;   /* compatibility */    void *shm_unused2;           /* ditto - used by DIPC */    void *shm_unused3;           /* unused */};

接下来看shmget函数,很明显创建及关联(通俗地说就是读取)共享内存都需要使用该函数,创建和读取时使用的参数不同。其中那个shmflag标志其实很明显,百度文档说的蛮清楚了,如果是简单的创建的则用IPC_CREATE,这样铁定会回传一个共享内存的id(供之后的shmat,读写共享内存用),如果希望发现之前已经有过一次相同参数的创建,则加上IPC_EXCL,注意一点,,这个功能主要是为了严格鉴定出创建时的情况,但是返回报错也是一个悲伤的事情。如果设定为0,则只能读取了。主从端设定位 CREATE|EXCL 及 0是一组严谨的组合,推荐使用。另外格外注意一点,CREATE选项必须和0600合并使用 ,就是CREATE|0600,这是用于确认读写权限的选项,如果不加,可能发生的情况是创建的进程自己都不能读写自己创建的共享内存。

相关的shmat是为了进程能够对已经关联的内存进行读写。理论上shmget和shmat当然是接在一起用更合理(否则共享内存的id用什么办法来传输呢?)这个shmat没有什么特别的,如果你希望他将共享内存映射到你的指定内存地址里,那就使用那个shmaddr形参。如果你想让操作系统来更合理的安排,则如下代码更合理

char *shm;shm = shmat(shmid,0,0); //可以看到你没有new char shm,所以等下也不用delete shm,因为操作系统会替你释放空间。

最后是shmdt,这个函数没什么特别的,简单易用,你忘记了也没啥大事(真的么?我开玩笑而已,不要忘记啦),但是请看清说明,这只是将当前进程内存映射断开,并没有真正释放共享内存,想要释放共享内存,还是需要用shmctl!


好了,简单入门就到这里,如果想要进一步了解,请查阅linux系统手册,或者这里还有一篇略深的博客: 传送门


0 0
原创粉丝点击