Linux进程间通信(IPC)教程 Linux共享内存介绍:介绍POSIX共享内存的基本概念、用途和编程实践

简介: Linux进程间通信(IPC)教程 Linux共享内存介绍:介绍POSIX共享内存的基本概念、用途和编程实践

POSIX共享内存概述

共享内存是最高效的IPC机制,因为它不涉及进程之间的任何数据传输。

这种高效率带来的问题是,我们必须用其他辅助手段来同步进程对共享内存的访问,否则会产生竞态条件。

因此,共享内存通常和其他进程间通信方式一起使用。
Linux下有三种共享内存的IPC技术:System V共享内存、共享文件映射(mmap)、POSIX共享内存。 本文只介绍POSIX共享内存。

POSIX共享内存和POSIX消息队列,有名信号量一样都是具有随内核持续性的特点。


POSIX共享内存流程

  1. 指定一个名字参数调用shm_open,以创建一个新的共享内存区对象或打开一个已存在的共享内存区对象.
  2. 调用mmap把这个共享内存区映射到调用进程的地址空间.

和内存映射文件进行通信的使用上差别在于mmap描述符参数获取方式不一样

如下图所示:


POSIX共享内存相关接口

  • 创建/打开共享内存区对象
#include <sys/mman.h>
int shm_open(const char *name, int oflag, mode_t mode);//成功返回非负的描述符,失败返回-1

参数:

name:POSIX IPC的名字,前面关于POSIX进程间通信都已讲过关于POSIX IPC的规则,这里不再赘述。

oflag:操作标志,包含:O_RDONLY,O_RDWR,O_CREAT,O_EXCL,O_TRUNC。其中O_RDONLY和O_RDWR标志必须且仅能存在一项。

mode:用于设置创建的共享内存区对象的权限属性。和open以及其他POSIX IPC的xxx_open函数不同的是,该参数必须一直存在,如果oflag参数中没有O_CREAT标志,该位可以置0;

注意:

这里的name不能写成/tmp/aaa.sem这样的格式,因为在linux下,sem都是创建在/dev/shm目录下。

你可以将name写成“/mysem”或“mysem”,创建出来的文件都是“/dev/shm/sem.mysem”,千万不要写路径。也千万不要写“/tmp/mysem”之类的。

返回值:

    若成功,返回指向信号量的指针

    若失败,返回SEM_FAILED

  • 删除共享内存区对象
int shm_unlink(const char *name);
//shm_unlink用于删除一个共享内存区对象,跟其他文件的unlink以及其他POSIX IPC的删除操作一样,对象的析构会到对该对象的所有引用全部关闭才会发生。

参数:

name: 共享内存区对象的名字

返回值:

    若成功,返回0

    若失败,返回-1


POSIX共享内存使用例程

  • 创建共享内存区,并写入
   
    int     shm_fd   = 0;
    char *  shm_data = NULL;  
    char    shm_buf[1024]={0};
  
    shm_fd = shm_open("shm-update", O_CREAT|O_RDWR, 0777);
 
    if (shm_fd < 0)
    {
      perror("fail to shm_open");
    }
    else
    {
      //调整确定文件共享内存的空间
      ftruncate(shm_fd, 1024);
      if(ftruncate(shm_fd, 1024)== -1)
      {
          perror("ftruncate shm_fd failed");
      }
      //映射目标文件的存储区
      shm_data = mmap(NULL,1024, PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, SEEK_SET);
      if(NULL == shm_data)
      {
        perror("fail to mmap");
      }
    }
 
    shm_buf[0]='1';
    memcpy(shm_data,shm_buf,sizeof(shm_buf));
  • 打开共享内存区,并读取
       
    int     shm_fd   = 0;
    char *  shm_data = NULL;  
 //   char    shm_buf[1024]={0};
 
    shm_fd = shm_open("shm-update", O_RDWR, 0777);
 
    if (shm_fd < 0)
    {
          perror("fail to shm_open");
    }
    else
    {
      //调整确定文件共享内存的空间
      ftruncate(shm_fd, 1024);
      if(ftruncate(shm_fd, 1024)== -1)
      {
          perror("fail to ftruncate");
      }
      //映射目标文件的存储区
      shm_data = mmap(NULL,1024, PROT_READ, MAP_SHARED, shm_fd, SEEK_SET);
      if(NULL == shm_data)
      {
          perror("fail to mmap");
      }
    }
 
    printf("shm_buf:%s-%d",shm_data,*shm_data);


目录
相关文章
|
4天前
|
算法 调度 UED
深入理解操作系统内存管理:原理与实践
【4月更文挑战第23天】 在现代计算机系统中,操作系统的内存管理是保证系统高效、稳定运行的关键组成部分。本文旨在深入探讨操作系统中内存管理的理论基础、关键技术以及实际操作过程,通过对内存分配策略、虚拟内存技术、分页与分段机制等核心概念的详细解析,为读者提供一个清晰、全面的内存管理视角。此外,文章还将通过案例分析,展示内存管理在解决实际问题中的应用,以期加深读者对操作系统内存管理复杂性的认识和理解。
|
16天前
|
安全 Java 数据处理
Python网络编程基础(Socket编程)多线程/多进程服务器编程
【4月更文挑战第11天】在网络编程中,随着客户端数量的增加,服务器的处理能力成为了一个重要的考量因素。为了处理多个客户端的并发请求,我们通常需要采用多线程或多进程的方式。在本章中,我们将探讨多线程/多进程服务器编程的概念,并通过一个多线程服务器的示例来演示其实现。
|
1月前
|
消息中间件 存储 算法
【软件设计师备考 专题 】操作系统的内核(中断控制)、进程、线程概念
【软件设计师备考 专题 】操作系统的内核(中断控制)、进程、线程概念
83 0
|
1月前
|
存储 算法 Linux
【Linux 应用开发 共享内存】深入理解和实践 ftruncate:共享内存的有效管理
【Linux 应用开发 共享内存】深入理解和实践 ftruncate:共享内存的有效管理
62 5
|
1月前
|
Shell Linux C语言
【Shell 命令集合 磁盘维护 】Linux 创建一个初始化内存盘 mkinitrd命令使用教程
【Shell 命令集合 磁盘维护 】Linux 创建一个初始化内存盘 mkinitrd命令使用教程
36 0
|
3天前
|
Java API 调度
[Java并发基础]多进程编程
[Java并发基础]多进程编程
|
3天前
|
NoSQL Linux 程序员
【linux进程信号(一)】信号的概念以及产生信号的方式
【linux进程信号(一)】信号的概念以及产生信号的方式
|
3天前
|
存储 Linux Shell
【linux进程(一)】深入理解进程概念--什么是进程?PCB的底层是什么?
【linux进程(一)】深入理解进程概念--什么是进程?PCB的底层是什么?
|
18天前
|
存储 算法
深入理解操作系统内存管理:原理与实践
【4月更文挑战第8天】 在现代计算机系统中,操作系统扮演着关键角色,特别是在内存资源的管理上。本文将深入探讨操作系统中的内存管理机制,包括虚拟内存、物理内存的分配与回收,以及页面置换算法等关键技术。通过分析不同内存管理策略的优势与局限性,本文旨在为读者提供一套系统的内存管理知识框架,帮助理解操作系统如何高效、安全地管理有限的内存资源以满足多任务处理的需求。
|
25天前
|
存储 算法 安全
深入理解操作系统内存管理:原理与实践
【4月更文挑战第2天】 在现代计算机系统中,操作系统的内存管理是核心功能之一,它负责协调和分配系统内存资源。本文将探讨操作系统内存管理的基本原理,包括内存的分配与回收、分页机制、虚拟内存的使用以及内存保护。通过对这些概念的细致剖析,我们不仅能够理解操作系统如何高效利用有限的物理内存,还能够认识到内存管理对系统稳定性和性能的重要性。文章还将简要讨论现代操作系统中内存管理的创新趋势及其对未来计算技术的潜在影响。
15 2