Linux进程间通信之共享内存

一,共享内存
  内核管理一片物理内存,允许不同的进程同时映射,多个进程可以映射同一块内存,被多个进程同时映射的物理内存,即共享内存。
  映射物理内存叫挂接,用完以后解除映射叫脱接

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<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#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<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#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:

时间: 2024-08-07 08:28:09

Linux进程间通信之共享内存的相关文章

Linux进程间通信—使用共享内存

Linux进程间通信-使用共享内存 转自: https://blog.csdn.net/ljianhui/article/details/10253345 下面将讲解进程间通信的另一种方式,使用共享内存. 一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式.不同进程之间共享的内存通常安排为同一段物理内存.进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像

Linux进程间通信——使用共享内存

下面将讲解进程间通信的另一种方式,使用共享内存. 一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式.不同进程之间共享的内存通常安排为同一段物理内存.进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言函数malloc分配的内存一样.而如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程. 特别提醒:共

Linux进程间通信--mmap共享内存(一)

共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式.两个不同进程A.B共享内存的意思是,同一块物理内存被映射到进程A.B各自的进程地址空间.进程A可以即时看到进程B对共享内存中数据的更新,反之亦然.由于多个进程共享同一块内存区域,必然需要某种同步机制,互斥锁和信号量都可以. 采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝.对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存则只拷贝两次数据[1]:一次从输入

Linux进程间通信--shmget()共享内存(二)

共享内存区域是被多个进程共享的一部分物理内存.如果多个进程都把该内存区域映射到自己的虚拟地址空间,则这些进程就都可以直接访问该共享内存区域,从而可以通过该区域进行通信.共享内存是进程间共享数据的一种最快的方法,一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容.这块共享虚拟内存的页面,出现在每一个共享该页面的进程的页表中.但是它不需要在所有进程的虚拟内存中都有相同的虚拟地址. 图 共享内存映射图 象所有的 System V IPC对象一样,对于共享内存对象的获取

Linux进程间通信--mmap()共享内存(二)

内核怎样保证各个进程寻址到同一个共享内存区域的内存页面 1.page cache及swap cache中页面的区分:一个被访问文件的物理页面都驻留在page cache或swap cache中,一个页面的所有信息由struct page来描述.struct page中有一个域为指针mapping ,它指向一个struct address_space类型结构.page cache或swap cache中的所有页面就是根据address_space结构以及一个偏移量来区分的. 2.文件与addres

Linux进程间通信--shmget()共享内存(一)

大多数共享内存的具体实现,都是把由不同进程之间共享的内存映射为同一段物理内存. 多个进程都把该物理内存区域映射到自己的虚拟地址空间,这些进程就都可以直接访问该共享内存区域,从而可以通过该区域进行通信. 共享内存允许两个不相关的进程访问同一段物理内存, 由于数据不需要在不同的进程间复制,所以它是在两个正在运行的进程之间传递数据的一种非常有效的方式,一个进程向共享内存区域写入数据,共享该区域的所有进程就可以立刻看到其中的数据内容. 注意: 1.如上图所示,共享虚拟内存的页面,出现在每一个共享该页面的

Linux进程间通信——使用共享内存(转)

这篇文章将讲述别一种进程间通信的机制--信号量.注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物.有关信号的更多内容,可以阅读我的另一篇文章:Linux进程间通信--使用信号.下面就进入信号量的讲解. 一.什么是信号量 为了防止出现因多个程序同时访问一个共享资源而引发的一系列问题,我们需要一种方法,它可以通过生成并使用令牌来授权,在任一时刻只能有一个执行线程访问代码的临界区域.临界区域是指执行数据更新的代码需要独占式地执行.而信号量就可以提供这样的一种访问机制,让一个临界区同

linux进程间通信之共享内存学习记录

进程 狭义定义:进程是正在运行的程序的实例(an instance of a computer program that is being executed). 广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动.它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元. 进程的概念主要有两点:第一,进程是一个实体.每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region).数据区域(data region)和堆

Linux进程IPC浅析[进程间通信SystemV共享内存]

Linux进程IPC浅析[进程间通信SystemV共享内存] 共享内存概念,概述 共享内存的相关函数 共享内存概念,概述: 共享内存区域是被多个进程共享的一部分物理内存 多个进程都可把该共享内存映射到自己的虚拟内存空间,所有用户空间的进程若要操作共享内存,都要将其映射到自己的虚拟内存空间中,通过映射的虚拟内存空间地址去操作共享内存,从而达到进程间的数据通信 共享内存是进程间共享数据的一种最快的方法,一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容 本身不提供同