1. 概述

System V共享内存在概念上类似于Posix共享内存,代之以调用shm_Open后调用mmap的是,先调用shmget,再调用shmat。

对于每个System V共享内存,内核都维护如下的信息结构,它定义在sys/shm.h头文件中,其中带注释的是我们需要关注的成员。

  1. struct shmid_ds
  2. {
  3. struct ipc_perm shm_perm;
  4. size_t shm_segsz; //共享内存区大小
  5. pid_t shm_lpid;
  6. pid_t shm_cpid;
  7. shmatt_t shm_nattch;
  8. shmat_t shm_cnattch;
  9. time_t shm_atime;
  10. time_t shm_dtime;
  11. time_t shm_ctime;
  12. };

2. System V共享内存API

shmget

shmget用于创建一个新的共享内存或打开一个已存在的共享内存。

  1. //成功返回共享内存标识符,
  2. int shmget(key_t key, size_t size, int oflag);
  • 参数size是共享内存区大小,其余两个参数含义及用法和System V信号量一样
  • 当实际操作为创建新的共享内存时,该内存区size个字节均被初始化为0
  • 当实际操作为打开已有共享内存时,size可设为0,oflag设为需要的读写权限

shmat

shmat用于把shmget创建或打开的共享内存连接到调用进程的地址空间。

  1. //成功返回映射区起始地址,失败返回-1
  2. void *shmat(int shmid, const void *shmaddr, int flag);
  • shmid是shmget返回的标识符
  • shmaddr推荐设为NULL,表示由系统决定映射区起始地址
  • flag一般设为0,因为只要调用进程具有共享内存的读写权限,那么映射区内存就也可以读写
  • flag也可以设为SHM_RDONLY限定只读访问

shmdt

shmdt删除由shmat建立的连接。

  1. //成功返回0,失败返回-1
  2. int shmdt(const void *shmaddr);

shmctl

shmctl用于对共享内存的各种控制操作。

  1. //成功返回0,失败返回-1
  2. int shmctl(int shmid, int cmd, struct shmid_ds *buf);

cmd可使用的命令有三个:

  • IPC_RMID:从系统中删除共享内存,此时buf参数设为NULL即可
  • IPC_STAT:通过buf返回共享内存对应的shmid_ds结构,一般用此命令获取共享内存区大小
  • IPC_SET:通过buf设置共享内存对应shmid_ds结构中的shm_perm.uid、shm_perm.gid和shm_perm.mode

3. 简单的程序

代码实现

common.h

  1. #ifndef _COMMON_H_
  2. #define _COMMON_H_
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <sys/types.h>
  7. #include <sys/ipc.h>
  8. #include <sys/shm.h>
  9. #define FTOK_FILE "/home/delphi/ftok.file"
  10. #define FTOK_ID 1
  11. #define SHM_RD_PERMISSION 0444
  12. #define SHM_WR_PERMISSION 0222
  13. #define SHM_RW_PERMISSION (SHM_RD_PERMISSION | SHM_WR_PERMISSION)
  14. #endif

shmcreate.c

  1. #include "common.h"
  2. int main(int argc, char **argv)
  3. {
  4. int length = atoi(argv[1]);
  5. int oflag = IPC_CREAT | SHM_RW_PERMISSION;
  6. int shmid = shmget(ftok(FTOK_FILE, FTOK_ID), length, oflag);
  7. if (shmid >= 0)
  8. {
  9. printf("shmget create success, shmid = %d\n", shmid);
  10. }
  11. return 0;
  12. }

shmrmid.c

  1. #include "common.h"
  2. int main(int argc, char **argv)
  3. {
  4. int shmid = shmget(ftok(FTOK_FILE, FTOK_ID), 0, SHM_RW_PERMISSION);
  5. shmctl(shmid, IPC_RMID, NULL);
  6. return 0;
  7. }

shmwrite.c

  1. #include "common.h"
  2. int main(int argc, char **argv)
  3. {
  4. int shmid;
  5. unsigned char *shmadd;
  6. struct shmid_ds buf;
  7. int i;
  8. shmid = shmget(ftok(FTOK_FILE, FTOK_ID), 0, SHM_RW_PERMISSION);
  9. shmadd = shmat(shmid, NULL, 0);
  10. shmctl(shmid, IPC_STAT, &buf);
  11. for (i = 0; i < buf.shm_segsz; i++)
  12. {
  13. *shmadd++ = i % 256;
  14. }
  15. return 0;
  16. }

shmread.c

  1. #include "common.h"
  2. int main(int argc, char **argv)
  3. {
  4. int shmid;
  5. unsigned char *shmadd;
  6. unsigned char v;
  7. struct shmid_ds buf;
  8. int error = 0;
  9. int i;
  10. shmid = shmget(ftok(FTOK_FILE, FTOK_ID), 0, SHM_RW_PERMISSION);
  11. shmadd = shmat(shmid, NULL, 0);
  12. shmctl(shmid, IPC_STAT, &buf);
  13. for (i = 0; i < buf.shm_segsz; i++)
  14. {
  15. v = *shmadd++;
  16. if (v != (i % 256))
  17. {
  18. printf("error: shmadd[%d] = %d\n", i, v);
  19. error++;
  20. }
  21. }
  22. if (error == 0)
  23. {
  24. printf("all of read is ok\n");
  25. }
  26. return 0;
  27. }

代码测试

System V共享内存的更多相关文章

  1. Linux进程通信之System V共享内存

    前面已经介绍过了POSIX共享内存区,System V共享内存区在概念上类似POSIX共享内存区,POSIX共享内存区的使用是调用shm_open创建共享内存区后调用mmap进行内存区的映射,而Sys ...

  2. 阐述linux IPC(五岁以下儿童):system V共享内存

    [版权声明:尊重原创.转载请保留源:blog.csdn.net/shallnet 要么 .../gentleliu,文章学习交流,不用于商业用途]         system V共享内存和posix ...

  3. UNIX环境高级编程——System V 共享内存区

    共享内存区域是被多个进程共享的一部分物理内存.如果多个进程都把该内存区域映射到自己的虚拟地址空间,则这些进程就都可以直接访问该共享内存区域,从而可以通过该区域进行通信.共享内存是进程间共享数据的一种最 ...

  4. Linux IPC实践(9) --System V共享内存

    共享内存API #include <sys/ipc.h> #include <sys/shm.h> int shmget(key_t key, size_t size, int ...

  5. php进程(线程)通信基础--System V共享内存

    PHP默认情况没有开启功能,要支持该功能在编译PHP的时候要加入下面几个选项  System V消息,--enable-sysvmsg   System V信号量支持,--enable-sysvsem ...

  6. System V 共享内存区

    1.概述 系统调用mmap通过映射一个普通文件实现共享内存.System V 则是通过映射特殊文件系统shm中的文件实现进程间的共享内存通信.也就是说,每个共享内存区域对应特殊文件系统shm中的一个文 ...

  7. System V共享内存介绍

    (一)简单概念 共享内存作为一种进程间通信的方式,其相较于其他进程间通信方式而言最大的优点就是数据传输速率快.其内部实现的方式采用了Linux进程地址空间中的mmap文件映射区,将文件内容直接映射到各 ...

  8. 共享内存之——system V共享内存

    System V 的IPC对象有共享内存.消息队列.信号灯(量). 注意:在IPC的通信模式下,不管是共享内存.消息队列还是信号灯,每个IPC的对象都有唯一的名字,称为"键(key)&quo ...

  9. Linux system v 共享内存

    system v 共享内存 #include <sys/types.h> #include <sys/shm.h> int shmget(key_t key, size_t s ...

随机推荐

  1. WebGL调试工具分享

    学习WebGL,我们需要一些好用的调试工具,下面分享3个常用的调试工具. WebGL Inspector 下载地址:https://github.com/benvanik/WebGL-Inspecto ...

  2. net::ERR_ABORTED 404 (Not Found)

    对于按需加载(on-demand-load)或加载外部资源(external resources)(如图片.文件等)来说,webpack的配置,output.publicPath是很重要的选项.如果指 ...

  3. 【OpenCV开发】OpenCV3后IPLimage转换成MAT的问题

    IplImage* img1 = cvCreateImage(cvGetSize(resizeRes), IPL_DEPTH_8U, 1);//创建目标图像 Mat test = img1;  报错 ...

  4. laravel composer vendor 目录加载类库详细 之后做说明

    composer installLoading composer repositories with package informationInstalling dependencies (inclu ...

  5. CentOS 初始化脚本

    #!/bin/bash # curl https://yiyingcanfeng.github.io/centos-init.sh | bash # 可选参数base kernel python ph ...

  6. 【转】Axure RP9.0.0.3661Team Edition激活码

    被授权人:Axure 授权密码:ydiJnG8quHEhHLu/MWonjkeul5LYB1+tX9fyPVnpdmU0cb/NJzVs45uD7z5Iswmi 转载于:http://menvscod ...

  7. mybatis中封装结果集常见示例

    1.返回一个对象 public interface EmployeeMapper { public Employee getEmpByMap(Map<String, Object> map ...

  8. 2.RabbitMQ 的可靠性消息的发送

      本篇包含 1. RabbitMQ 的可靠性消息的发送 2. RabbitMQ 集群的原理与高可用架构的搭建 3. RabbitMQ 的实践经验   上篇包含 1.MQ 的本质,MQ 的作用 2.R ...

  9. R学习笔记1 介绍R的使用

    R脚本的一次执行叫做一个会话(Session),可以通过函数quit()退出当前的会话 quit(save = "default", status = 0, runLast = T ...

  10. wait(),notify(),notifyAll()必须加锁的原因

    从语义方面解析为什么需要锁: 1.wait()方法会释放锁,如果没有先获得锁,那么如何释放? 从实际的作用: 为了预防饥饿线程的产生. 原因: // 线程A 的代码 while(!condition) ...