linux C 语言开发 (十一) 进程间通讯--共享内存

Linux C共享内存通信详解

    文章的目的为了记录使用C语言进行linux 开发学习的经历。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。

    相关链接:

linux C 语言开发 (一) Window下用gcc编译和gdb调试

linux C 语言开发 (二) VsCode远程开发 linux

linux C 语言开发 (三) 建立云服务器

linux C 语言开发 (四) linux系统常用命令

linux C 语言开发 (五) linux系统目录结构

linux C 语言开发 (六) 程序的编辑和编译(vim、gcc)

linux C 语言开发 (七) 文件 IO 和标准 IO

linux C 语言开发 (八) 进程基础

linux C 语言开发 (九) 进程间通讯--管道

linux C 语言开发 (十) 进程间通讯--信号

linux C 语言开发 (十一) 进程间通讯--共享内存

linux C 语言开发 (十二) 进程间通讯--消息队列

Linux C到Android App开发推荐链接(入门十二章):

开源 java android app 开发(一)开发环境的搭建_csdn 开源 java android app-优快云博客

开源 java android app 开发(一)开发环境的搭建-优快云博客

开源 java android app 开发(二)工程文件结构-优快云博客

开源 java android app 开发(三)GUI界面布局和常用组件-优快云博客

开源 java android app 开发(四)GUI界面重要组件-优快云博客

开源 java android app 开发(五)文件和数据库存储-优快云博客

开源 java android app 开发(六)多媒体使用-优快云博客

开源 java android app 开发(七)通讯之Tcp和Http-优快云博客

开源 java android app 开发(八)通讯之Mqtt和Ble-优快云博客

开源 java android app 开发(九)后台之线程和服务-优快云博客

开源 java android app 开发(十)广播机制-优快云博客

开源 java android app 开发(十一)调试、发布-优快云博客

开源 java android app 开发(十二)封库.aar-优快云博客

linux C到.net mvc开发推荐链接:

开源C# .net mvc 开发(一)WEB搭建_c#部署web程序-优快云博客

开源 C# .net mvc 开发(二)网站快速搭建_c#网站开发-优快云博客

开源 C# .net mvc 开发(三)WEB内外网访问(VS发布、IIS配置网站、花生壳外网穿刺访问)_c# mvc 域名下不可訪問內網,內網下可以訪問域名-优快云博客

开源 C# .net mvc 开发(四)工程结构、页面提交以及显示_c#工程结构-优快云博客

开源 C# .net mvc 开发(五)常用代码快速开发_c# mvc开发-优快云博客

内容:讲述进程IPC通讯方式的内存共享。

目录:

1.基本介绍

2.常用函数

3.源码分析

4.效果演示






 

一、基本介绍
共享内存, 顾名思义就是允许两个不相关的进程访问同一个逻辑内存, 共享内存是两个正在运行的进程之间共享和传递数据的一种非常有效的方式。 不同进程之间共享的内存通常为同一段物理内存。 进程可以将同一段物理内存连接到他们自己的地址空间中, 所有的进程都可以访问共享内存中的地址。 如果某个进程向共享内存写入数据, 所做的改动将立即影响到可以访问同一段共享内存的任何其他进程。

二、常用函数

使用共享内存的步骤:

1.调用 shmget()创建共享内存段 id,

2.调用 shmat()将 id 标识的共享内存段加到进程的虚拟地址空间,

3.访问加入到进程的那部分映射后地址空间, 可用 IO 操作读写。

常用函数

函数int shmget(key_t key, size_t size, int shmflg)
参数 key由 ftok 生成的 key 标识, 标识系统的唯一 IPC 资源
参数 size需要申请共享内存的大小。 在操作系统中, 申请内存的最小单位为页, 一页是 4k 字节, 为了避免内存碎片, 我们一般申请的内存大小为页的整数倍。
参数 shmflg如果要创建新的共享内存, 需要使用 IPC_CREAT, IPC_EXCL, 如果是已经存在的, 可以使用 IPC_CREAT 或直接传 0
返回值成功时返回一个新建或已经存在的的共享内存标识符, 取决于 shmflg 的参数。失败返回-1 并设置错误码。
功能创建共享内存



 

函数key_t ftok(const char *pathname, int proj_id)
头文件#include <sys/types.h> #include <sys/ipc.h>
参数const char *pathname文件路径以及文件名
参数 int proj_id字符
返回值成功返回 key 值, 失败返回-1
功能建立 IPC 通讯(如消息队列、 共享内存时) 必须指定一个 ID 值。 通常情况下, 该 id 值通过 ftok 函数得到。



 

函数void *shmat(int shmid, const void *shmaddr, int shmflg)
头文件#include <sys/types.h> #include <sys/shm.h>
参数 int shmid共享内存的标识符, 也就是 shmget 函数的返回值
参数 const void *shmaddr映射到的地址, 一般写 NULL, NULL 为系统自动帮我完成映射
参数 int shmflg通常为 0, 表示共享内存可读可写, 或者为 SHM_RDONLY, 表示共享内存可读可写
返回值成功返回共享内存映射到进程中的地址, 失败返回-1
功能挂接共享内存

函数int shmdt(const void *shmaddr)
头文件#include <sys/types.h>
#include <sys/shm.h>
参数 const void *shmaddr共享内存映射后的地址
返回值成功返回 0, 失败返回-1
功能去关联共享内存
注意shmdt 函数是将进程中的地址映射删除, 也就是说当一个进程不需要共享内存的时候, 就可以使用这个函数将他从进程地址空间中脱离, 并不会删除内核里面的共享内存对象。

函数int shmctl(int shmid, int cmd, struct shmid_ds *buf)
头文件#include <sys/ipc.h> #include <sys/shm.h>
参数 int shmid要删除的共享内存的标识符
参数 int cmdIPC_STAT (获取对象属性) IPC_SET (设置对象属性) IPC_RMID(删除对象)
参数 struct shmid_ds *buf指定 IPC_STAT (获取对象属性) IPC_SET (设置对象属性) 时用来保存或者设置的属性
功能销毁共享内存

三、源码分析

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
    int shmid;
    key_t key;
    pid_t pid;
    char *s_addr, *p_addr;
    key = ftok("./a.c", 'a');
    shmid = shmget(key, 1024, 0777 | IPC_CREAT);
    if (shmid < 0)
    {
        printf("shmget is error\n");
        return -1;
    } 
    printf("shmget is ok and shmid is %d\n", shmid);
    pid = fork();
    if (pid > 0)
    {
        p_addr = shmat(shmid, NULL, 0);
        strncpy(p_addr, "hello", 5);
        wait(NULL);
        exit(0);
    } 
    if (pid == 0)
    {
        sleep(2);
        s_addr = shmat(shmid, NULL, 0);
        printf("s_addr is %s\n", s_addr);
        exit(0);
    } 
    return 0;
}

这段代码的主要功能是:

创建一个共享内存段。

创建一个子进程。

父进程向共享内存段写入字符串 "hello"。

子进程等待2秒后,从同一个共享内存段读取并打印该字符串。

四、效果演示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值