C语言共享内存

时间:2022-07-22
本文章向大家介绍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: %dn", shmid);

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

    // 拷贝共享数据到共享内存
    printf("copy data to shared-memoryn");
    bzero(shmadd, BUFFSIZE);
    msg = "hello, yj.";
    strcpy(shmadd, msg);
    printf("copy data to shared-memory success, with msg: %sn", 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: %dn", shmid);

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

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

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

    // 删除共享内存
    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消息),或生成信号的方法来提供读写之间的更有效的同步机制。