文档章节

C语言共享内存

明天以后
 明天以后
发布于 2017/09/01 11:06
字数 779
阅读 137
收藏 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
博文 128
码字总数 85743
作品 0
昌平
程序员
私信 提问
System.IO之内存映射文件共享内存

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

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

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

daleshen128
2012/12/15
217
3
c语言怎么生成唯一的序列

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

陈舵主
2013/01/04
1K
9
C语言共享内存使用思路利用结构体

这里不介绍如何创建共享内存,如果想知道百度一下就好了。只介绍一下如何使用这一段连续的共享内存空间。思路就是利用结构体。 创建一个结构体,它的大小可以用sizeof()获取。注意这里有一...

kangxin1234
2015/09/28
895
0
C 语言编写的内存数据库 - STVM

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

DeffPuzzL
2018/03/02
0
1

没有更多内容

加载失败,请刷新页面

加载更多

虚拟化 - KVM 和 Xen 比较

Linux虚拟化技术的用户目前有两种免费的开源管理程序可以选择:Xen和KVM。 作为较早出现的虚拟化技术,Xen是“第一类”运行在裸机上的虚拟化管理程序(Hypervisor),也是当前相当一部分商业...

临江仙卜算子
30分钟前
1
0
给windows server中的“未识别的网络”或“无法识别的网络”设置网络位置类型

在windows server中,如果网络没有被正确的识别,那么就需要手工设置一下网络位置类型。 将“公用网络”指定设置为“专用网络“ 【控制面板】--【系统和安全】--【管理工具】--【本地安全策略...

gugudu
今天
2
0
阿里强制要求的21条Java开发规范,可以避免很多坑

1. 【强制】避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用类名来访问即可。 2. 【强制】所有的覆写方法,必须加@Override注解。 说明:getObject...

天王盖地虎626
今天
10
0
oracle dg 备库未设置convert参数导致ORA-01111,ORA-01110

查看trace 文件: MRP0: Background Managed Standby Recovery process started (amls) started logmerger process Sun Jan 20 07:55:53 2019 Managed Standby Recovery starting Real Time ......

hnairdb
今天
2
0
乱入Linux界的我是如何学习的

欢迎来到建哥学Linux,咳!咳!咳!开个玩笑哈,我是一个IT男,IT界的入门选手,正在学习Linux。 在之前,一直想进军IT界,学习IT技术,但是苦于没有人指导,也不知道学什么,最开始我自己在...

linux-tao
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部