Linux_4.8_共享内存通信

共享内存


(1)基本概念:




共享内存使用4步:




1 创建/打开共享内存

1.1 函数名

shmget

1.2 函数原形

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

1.3 函数功能

分配一个共享内存段

1.4 所属头文件

#include <sys/ipc.h>

#include <sys/shm.h>

1.5 返回值

成功:返回共享内存标识符

失败:返回-1

1.6 参数说明

key:标识共享内存的键值:0/IPC_PRIVATE.

当key的取值为IPC_PRIVATE,则函数shmget()将创建一块新的共享内存,大小由size决定;

当key的取值为0,而参数shmflg设置为IPC_PRIVATE这个标识,则同样会创建一块新的共享内存

   key取值不为IPC_PRIVATE时,而且也不是已建立的共享内存IPC key,则视参数shmflg中是否有IPC_CREAT标志,来决定是否建立新的共享内存,并且以key值为新共享内存的IPC key。如果没有IPC_CREAT标志,则会返回错误。

   key取值为已建立的共享内存IPC key时,如果参数shmflg中包含IPC_CREATIPC_EXCL,则返回错误。如果只包含这两个标志中的其中之一,或者两个都不包含,则视size的大小是否小于等于这个已存在的共享内存的大小,如果小于等于,则返回这个共享内存的ID标识符;否则,返回错误。

     参数shmflg也可以用来设置共享内存的存取权限,其值相当于open()函数的mode用法,执行位不用。



size:设置申请共享内存的大小


shmflg:创建的标志


2 映射共享内存

2.1 函数名

shmat

2.2 函数原形

void *shmat(int shmid,const void *shmaddr,int shmflg)

2.3 函数功能

共享内存操作

2.4 所属头文件

#include<sys/types.h>

#include<sys/shm.h>

2.5 返回值

成功:返回共享内存映射到进程中的地址

失败:返回-1

2.6 参数说明

       shmid为共享内存ID标识符。

       shmaddr指定映射的地址:

如果shmaddr0,则由内核自动分配。

如果不为0shmflg也没有指定IPC_RND旗标,则以参数shmaddr为连接地址。

如果不为0shmflg指定了IPC_RND旗标,则将自动将参数shmflg调整为SHMLBA的整数倍。

SHMLBA的定义有两种情况,如下:

#define   SHMLBA   PAGE_SIZE

#define   SHMLBA   (4 * PAGE_SIZE)

 

shmflg还可以有SHM_RDONLY,表示映射的内存只可以读。

 

附加说明:1.在经过fork()之后,映射的地址会被继承到子进程。

               2.在经过exec()之后,映射的地址连接会自动脱离。

               3.程序运行结束之后,映射的地址连接也会自动脱离。





3 分离共享内存

3.1 函数名

shmdt

3.2 函数原形

int shmdt(const void * shmaddr)

3.3 函数功能

解除共享内存映射


3.4 所属头文件

#include<sys/types.h>

#include<sys/shm.h>


3.5 返回值

成功:返回0

否则:返回-1

错误原因存于errno

3.6 参数说明

shmaddr:shmat()映射后获得的地址


4 删除共享内存

4.1 函数名

shmctl

4.2 函数原形

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

4.3 函数功能

控制共享内存的操作

4.4 所属头文件

#include<sys/ipc.h>

#include<sys/shm.h>


4.5 返回值

成功:0

出错:-1,错误原因存于error中

4.6 参数说明

shmid:为共享内存的ID标识符

buf:共享内存管理结构体。

cmd:为操作的命令

buf:

  IPC_STAT          把共享内存的shmid_ds结构数据复制到buf(每个共享内存中,都包含有一个shmid_ds结构,里面保存了一些关于本共享内存的信息)

     IPC_SET           将参数所指的shmid_ds结构中的shm_perm.uidshm_perm.gidshm_perm.mode复制到共享内存的shmid_ds结构内。

     IPC_RMID          删除共享内存和其包含的数据结构

     SHM_LOCK         不让此共享内存置换到 swap    (什么是swap,这个本人也不理解,如果有高手知道,希望不吝赐教)

     SHM_UNLOCK      允许此共享内存置换到swap

     SHM_LOCKSHM_UNLOCKLinux特有,且唯有超级用户允许使用。

 

     shmid_ds结构定义(linux-2.6.32.2):

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 */

};

 

shm_segsz        共享内存的大小(bytes)

shm_atime        最后一次attach(映射)此共享内存的时间

shm_dtime        最后一次detach(解除映射)此共享内存的时间

shm_ctime        最后一次更动此共享内存的时间。

shm_cpid         建立此共享内存的进程识别码。

shm_lpid          最后一个操作此共享内存的进程识别码。


实例:

#include <unistd.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#define KEY          1234

#define SIZE         1024

int main()

{     int shmid;

       char *shmaddr;

       struct shmid_ds buf;

       shmid = shmget(KEY, SIZE, IPC_CREAT | 0600);    /*建立共享内存*/

       if (fork() == 0)

       {

              shmaddr = (char *) shmat(shmid, 0, 0);

              strcpy(shmaddr, "Hi! I am Chiled process!/n");

              printf("Child:   write to shared memery: /"Hi! I am Chiled process!/"/n");

              shmdt(shmaddr);

              return;

       }

       else

       {

              sleep(3);      /*等待子进程执行完毕*/

              shmctl(shmid, IPC_STAT, &buf);          /*取得共享内存的状态*/

              printf("shm_segsz = %d bytes/n", buf.shm_segsz);

              printf("shm_cpid = %d/n", buf.shm_cpid);

              printf("shm_lpid = %d/n", buf.shm_lpid);

              shmaddr = (char*) shmat(shmid, 0, SHM_RDONLY);

              printf("Father:   %s/n", shmaddr);        /*显示共享内存内容*/

              shmdt(shmaddr);

              shmctl(shmid, IPC_RMID, NULL);         /*删除共享内存*/

       }

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值