专栏首页若是烟花C语言共享内存

C语言共享内存

共享内存是进程间通信中最简单的方式之一。共享内存允许两个或更多进程访问同一块内存,就如同 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消息),或生成信号的方法来提供读写之间的更有效的同步机制。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 当你在`bind 0.0.0.0`的时候,你实际在做什么

    如上面的 TCP *:5000 (LISTEN) 中 * 便表示 0.0.0.0。在这种情况下,他是一个缺省的路由绑定。

    lpe234
  • 关于Hibernate懒加载----Spring filter

    比如部门ENTITY和员工ENTITY,部门与员工1对多,如果lazy设置为 false,那么只要加载了一个部门的po,就会根据一对多配置的关系把所有员工的po...

    lpe234
  • Solr基本搭建及MySQL配置

    启动后访问 http://127.0.0.1:8983/, 理论上即可进入Solr管理界面。具体内容见Solr Admin UI

    lpe234
  • Spring Security入门到实践(二)表单认证实践及原理分析

    登录认证功能是我们在日常生活中使用到最多的功能之一,现在互联网应用基本都具备表单登录能力,基本的思路都是当用户访问一个需要登录后才能访问的功能,应用会提示用户没...

    itlemon
  • LeetCode 349:两个数组的交集 Intersection of Two Arrays

    Given two arrays, write a function to compute their intersection.

    爱写bug
  • EventBus3.0 使用及源码解析

    叨了个叨 最近因为换工作的一些琐事搞的我一个头两个大,也没怎么去学新东西,实在是有些愧疚。新项目用到了EventBus3.0,原来只是听说EventBus的鼎鼎...

    非著名程序员
  • 算法养成记:实现 strStr()

    Return the index of the first occurrence of needle in haystack, or -1 if needle ...

    三哥
  • 过去10年100款最酷科技产品:苹果iPhone 4、亚马逊ECHO、苹果MacBook Air荣登前三

    21世纪10年代的科技故事是一个“小玩意”一直从我们生活的各个角落流向世界各地的故事。现在,创造和消费文化的工具无处不在,为我们提供了令人难以置信的新功能,但同...

    新智元
  • 使用宝塔面板如何自动备份数据库和网站代码

    基础操作是:宝塔自带的定时任务当中就有备份数据库和网站代码啊 ? 然后就直接选择了备份到服务器磁盘

    沈唁
  • 数据结构Generic

    ​ 接下来我们要处理的是前面实现里另一个 根本性的缺陷 那些实现只适用于字符串,想要实现其他类型数据的队列和栈怎么办呢? 这个问题就涉及泛型的话题了。 ​...

    lwen

扫码关注云+社区

领取腾讯云代金券