文档章节

C语言共享内存

明天以后
 明天以后
发布于 2017/09/01 11:06
字数 779
阅读 64
收藏 1

共享内存是进程间通信中最简单的方式之一。共享内存允许两个或更多进程访问同一块内存,就如同 malloc() 函数向不同进程返回了指向同一个物理内存区域的指针。当一个进程改变了这块地址中的内容的时候,其它进程都会察觉到这个更改。

参考资料:

共享内存

linux进程间的通信(C): 共享内存

共享内存特点

  • 共享内存是进程间共享数据最快的方法

    一个进程向共享内存写入数据,共享这个内存区域的所有进程就可以立即看到其中的内容。

  • 使用共享内存需要注意的是多进程之间对一个给定存储区访问的互斥

    若一个进程正在向共享区写数据,则在它操作完成之前,其他的进程不应当去读、写这些数据。

示例代码如下

memShareWrite.c

//
// IPC--共享内存(写数据)
// Created by 卢鹏 on 2017/8/31.
//
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

// 共享内存大小
#define BUFFSIZE 1024

int main(int argc, char *argv[]) {
    // 共享内存的shmid
    int shmid;
    // 共享内存的key
    key_t key;
    char *shmadd;
    char *msg;

    // 创建共享内存的key
    if ((key = ftok("./", 2015)) == -1) {
        perror("ftok error");
    }

    // 创建共享内存
    if ((shmid = shmget(key, BUFFSIZE, IPC_CREAT|0666)) < 0) {
        perror("shmget error.");
        exit(-1);
    }
    printf("Create shared-memory success, with shmid: %d\n", shmid);

    // 映射
    if ((shmadd = shmat(shmid, NULL, 0)) < 0) {
        perror("shmat error.");
        exit(-1);
    }

    // 拷贝共享数据到共享内存
    printf("copy data to shared-memory\n");
    bzero(shmadd, BUFFSIZE);
    msg = "hello, yj.";
    strcpy(shmadd, msg);
    printf("copy data to shared-memory success, with msg: %s\n", msg);
}

memShareRead.c

//
// IPC--共享内存(读数据)
// Created by 卢鹏 on 2017/8/31.
//

#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFFSIZE 1024

int main(int args, char *argv[]) {
    int shmid;
    int ret;
    key_t key;
    char *shmadd;

    // 创建key值
    if ((key = ftok("./", 2015)) == -1) {
        perror("ftok error.");
    }

    // 查看系统共享内存
    printf("start-ipcs------------------------------------------\n");
    system("ipcs -m");
    printf("end-ipcs--------------------------------------------\n");

    // 打开共享内存
    if ((shmid = shmget(key, BUFFSIZE, IPC_CREAT|0666)) < 0) {
        perror("shmget error.");
        exit(-1);
    }
    printf("Open shared-memory success, with shmid: %d\n", shmid);

    // 映射
    if ((shmadd = shmat(shmid, NULL, 0)) < 0) {
        perror("shmat error.");
        exit(-1);
    }

    // 读取共享内存中的数据
    printf("read data from shared-memory\n");
    printf("%s\n", shmadd);

    // 分离共享内存和当前进程
    if ((ret = shmdt(shmadd)) < 0) {
        perror("shmdt error.");
        exit(1);
    } else {
        printf("Delete shared-memory\n");
    }

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

    // 查看系统共享内存
    printf("start-ipcs------------------------------------------\n");
    system("ipcs -m");
    printf("end-ipcs--------------------------------------------\n");

    return 0;
}

运行结果

➜ gcc memShareWrite.c -o w
➜ gcc memShareRead.c -o w
➜ chmod +x w
➜ chmod +x r
➜ 
➜
➜ ./w    
Create shared-memory success, with shmid: 327680
copy data to shared-memory
copy data to shared-memory success, with msg: hello, yj.

➜
➜
➜ ./r 
start-ipcs------------------------------------------
IPC status from <running system> as of Fri Sep  1 11:03:18 CST 2017
T     ID     KEY        MODE       OWNER    GROUP
Shared Memory:
m 327680 0xdf041eec --rw-rw-rw-   lpe234    staff

end-ipcs--------------------------------------------
Open shared-memory success, with shmid: 327680
read data from shared-memory
hello, yj.
Delete shared-memory
start-ipcs------------------------------------------
IPC status from <running system> as of Fri Sep  1 11:03:18 CST 2017
T     ID     KEY        MODE       OWNER    GROUP
Shared Memory:

end-ipcs--------------------------------------------


最后

但在实际编程中,应该使用信号量,或通过传递消息(使用管道或IPC消息),或生成信号的方法来提供读写之间的更有效的同步机制。

© 著作权归作者所有

共有 人打赏支持
明天以后
粉丝 71
博文 124
码字总数 82816
作品 0
昌平
程序员
System.IO之内存映射文件共享内存

内存映射文件是利用虚拟内存把文件映射到进程的地址空间中去,在此之后进程操作文件,就像操作进程空间里的地址一样了,比如使用c语言的memcpy等内存操作的函数。这种方法能够很好的应用在需...

长平狐
2012/06/08
130
0
关于如何更深度理解C之Volatile关键字

据我所知,在C语言中的volatile关键字,主要用在4个地方上。 1、 在内存中进行地址映射的设备寄存器 2, 在中断处理程序中可能被修改的全局变量 3, 多线程应用程序中的全局变量 4, 多进程应...

daleshen128
2012/12/15
210
3
PostgreSQL 共享缓存代码分析交流讲座

PostgreSQL 共享缓存代码分析交流讲座 方式:在线交流,使用QQ群语音。 时间:2013年12月17日晚8点开始。 交流之前,如果有如下准备更佳: 1、PostgreSQL v9.3.2源代码(或者9.0及更高版本,...

有理想的猪
2013/12/12
221
1
c语言怎么生成唯一的序列

c语言中,一个守护进程,在不设置int类型全局变量,也不能用时间(包括秒和毫秒)做种子调用rand()生成的伪随机情况下 怎么生成唯一序列码?rand既然叫伪随机,那有真随机的函数么? 还有,...

陈舵主
2013/01/04
1K
9
C 语言编写的内存数据库 - STVM

STVM(truck of Virtual memory table)是一个开源的使用ANSI C语言编写、支持本地API调用和网络调用,全表数据基于IPC共享内存方式存储, 基于C语言struck结构定义记录行,RB-Tree和hash作为...

DeffPuzzL
03/02
0
1

没有更多内容

加载失败,请刷新页面

加载更多

代理模式

自测: Q:何为代理模式? 代理是一种__或者__,控制对另一个对象的访问,而这些对象可能是__对象,______的对象,或者是对______的对象。 Q:那些角色及划分? 3个核心角色 角色一:____ 角...

阿元
44分钟前
1
0
面试经验

原文

火力全開
49分钟前
1
0
Kubernetes 教程(一) 环境安装并配置一个集群

Git<---------->jenkins docker<--------->kubernetes ?

MrPei
今天
1
0
linux学习-0919

linux和windows互传文件 用户配置文件和密码配置文件 用户组管理 用户管理 一、linux和windows互传文件 linux和windows可以互相传输文件,但是需要使用xshell 并且安装lrzsz包: yum insta...

wxy丶
今天
1
0
收集几个开源的微信小程序开发框架

1、 mpvue mpvue 是美团点评开源的一个使用 Vue.js 开发小程序的前端框架。框架基于 Vue.js 核心,mpvue 修改了 Vue.js 的 runtime 和 compiler 实现,使其可以运行在小程序环境中,从而为小...

哥本哈根的小哥
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部