程序员求职经验分享与学习资料整理平台

网站首页 > 文章精选 正文

Linux进程间通信之共享内存(linux共享内存使用的过程)

balukai 2025-03-20 12:18:50 文章精选 4 ℃

一,共享内存

内核管理一片物理内存,允许不同的进程同时映射,多个进程可以映射同一块内存,被多个进程同时映射的物理内存,即共享内存。

映射物理内存叫挂接,用完以后解除映射叫脱接

1,共享内存的特点:

优点:是最快的IPC。

缺点:要编程者自己实现对共享内存互斥访问。如何实现?

2,编程模型:具体函数的用法可以用man手册查看(强力推荐)

进程A: writeshm.c

1) 获得key, ftok

2) 使用key来创建一个共享内存 shmget

3) 映射共享内存(得到虚拟地址), shmat

4) 使用共享内存, 往共享内存中写入数据

5) 解除映射 shmdt

6) 如果共享内存不再使用,可以使用shmctl销毁共享内存

进程B: readshm.c

1) 获得key, ftok

2) 使用key来获得一个共享内存 shmget

3) 映射共享内存(得到虚拟地址), shmat

4) 使用共享内存, 读取共享内存中的数据

5) 解除映射 shmdt

3,实例

进程A:

// writeshm.c

#include
#include
#include
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>

int main
{
    // 生成一个key
    key_t key = ftok("./", 66);

    // 创建共享内存,返回一个id
    int shmid = shmget(key, 8, IPC_CREAT|0666|IPC_EXCL);
    if(-1 == shmid)
    {
        perror("shmget failed");
        exit(1);
    }

    // 映射共享内存,得到虚拟地址
    void *p = shmat(shmid, 0, 0);
    if((void*)-1 == p)
    {
        perror("shmat failed");
        exit(2);
    }

    // 写共享内存
    int *pp = p;
    *pp = 0x12345678;
    *(pp + 1) = 0xffffffff;

    // 解除映射
    if(-1 == shmdt(p))
    {
        perror("shmdt failed");
        exit(3);
    }
    printf("解除映射成功,点击回车销毁共享内存\n");
    getchar;

    // 销毁共享内存
    if(-1 == shmctl(shmid, IPC_RMID, NULL))
    {
        perror("shmctl failed");
        exit(4);
    }

    return 0;
}

进程B:

// readshm.c

#include
#include
#include
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>

int main
{
    // 生成一个key
    key_t key = ftok("./", 66);

    // 获取共享内存,返回一个id
    int shmid = shmget(key, 0, 0);
    if(-1 == shmid)
    {
        perror("shmget failed");
        exit(1);
    }

    // 映射共享内存,得到虚拟地址
    void *p = shmat(shmid, 0, 0);
    if((void*)-1 == p)
    {
        perror("shmat failed");
        exit(2);
    }

    // 读共享内存
    int x = *(int *)p;
    int y = *((int *)p + 1);
    printf("从共享内存中都取了:0x%x 和 0x%x \n", x, y);

    // 解除映射
    if(-1 == shmdt(p))
    {
        perror("shmdt failed");
        exit(3);
    }

    return 0;
}

运行结果:

writeshma:

readshma:

最近发表
标签列表