精华内容
下载资源
问答
  • 共享内存

    千次阅读 2018-10-09 17:34:43
    共享内存是常用的进程之间的通信,两个进程可以直接共享访问同一块内存区域 一:共享内存的实现步骤如下: (1)创建共享内存区 进程1通过操作系统提供的API从内存中申请一块共享区域,Linux系统中可以通过...

    共享内存是常用的进程之间的通信,两个进程可以直接共享访问同一块内存区域

    一:共享内存的实现步骤如下:

    (1)创建共享内存区

    进程1通过操作系统提供的API从内存中申请一块共享区域,Linux系统中可以通过shmget,函数实现,生成的共享内存块与某个特定的key进行绑定。

    (2)映射共享内存到进程1中

    在Linux环境中,可以通过shmat实现

    (3)映射共享内存到进程2中

    进程2通过进程1的shmat函数和同一个key值,然后执行shmat,将这个内存映射到进程2中。

    (4)进程1和进程2中相互通信

    共享内存实现两个映射后,可以利用该区域进行信息交换,由于没有同步机制,需要参与通信的进程自己协商处理

    (5)撤销内存映射关系

    完成通信之后,需要撤销之前的映射操作,通过shmdt实现

    (6)删除共享内存区

    在Linux中通过shctl函数来实现

    二:相关函数

    shmget函数:

    该函数用来创建共享内存,它的原型为:

     

    int shmget(key_t key,size_t size,int shmflg);

    该函数用来创建共享内存,它的原型为:

    第一个参数,与信号量的semget函数一样,程序需要提供一个参数key(非0整数),它有效地为共享内存命名

    shmget函数成功时返回一个与key相关的内存标识符(非负整数),用于后续的共享内存函数,调用失败返回-1.不相关的进程可以通过该函数的返回值访问同一共享内存,它代表程序可能要使用某个资源,程序对所有共享内存的访问都是间接的,程序先通过调用shmget函数并提供一个键,再由系统生成一个相应的共享内存标识符(shmget函数的返回值),只有shmget函数直接使用信号量键,所有其他的信号量函数再由semget函数返回的信号量表示符。

    第二个参数,size以字节为单位指定需要共享的内存容量

    第三个参数,shmflg是权限标志,它的作用与open函数的mode参数一样,如果要想在key标识的共享内存不存在时,创建它的话,可以与IPC_CREAT做或操作,共享内存的权限标志与文件的读写权限一样,举例来说,0644,它表示允许一个进程创建的共享内存被内存创建者所拥有的进程向共享内存读取和写入数据,同时其他用户创建的进程只能读取共享内存。

    2、shamt函数

    第一次创建完共享内存时,它还不能被任何进程访问,shmat函数的作用就是用来启动对该共享内存的访问,并把共享内存连接到当前进程的地址空间。它的原型如下:

     

    void *shamt(int shm_id,const void *shm_addr,int shmflg);

    第一个参数:shm_id是由shmget函数返回的共享内存标识

    第二个参数,shm_addr指定共享内存连接到当前进程中的地址位置,通常为空,表示让系统来选择共享内存的地址。

    第三个参数,shm_flg是一组标志位,通常为0。

    调用成功时返回一个指向共享内存第一个字节的指针,如果调用失败返回-1.

    3、shmdt函数

    该函数用于将共享内存从当前进程中分离。注意,将共享内存分离并不是删除它,只是使该共享内存对当前进程不再可用。它的原型如下:

     

    int shmdt(const void *shmaddr);

    参数shmaddr是shmat函数返回的地址指针,调用成功时返回0,失败时返回-1.

    4、shmctl函数

    与信号量的semctl函数一样,用来控制共享内存,它的原型如下:

     

    int shmctl(int shm_id,int command,struct shmin_ds *buf);

    第一个参数,shm_id是shmget函数返回的共享内存标识符

    第二个参数,command是要采取的操作,它可以取下面的三个值 :

        IPC_STAT:把shmid_ds结构中的数据设置为共享内存的当前关联值,即用共享内存的当前关联值覆盖shmid_ds的值。

        IPC_SET:如果进程有足够的权限,就把共享内存的当前关联值设置为shmid_ds结构中给出的值

        IPC_RMID:删除共享内存段

    第三个参数,buf是一个结构指针,它指向共享内存模式和访问权限的结构。

    shmid_ds结构至少包括以下成员:

     

    struct shmid_ds
    {
        uid_t shm_perm.uid;
        uid_t shm_perm.gid;
        mode_t shm_perm.mode;
    }

     

    展开全文
  • Linux共享内存共享内存API

    千次阅读 2018-01-23 16:31:45
    共享内存区是最快的IPC(进程间通信)形式。 用共享内存从服务器拷贝文件数据到客户端: 共享内存基本API: #include #include 1. int shmget(key_t key,size_t size,int shmflg); 功能:用来创建共享...

    共享内存区是最快的IPC(进程间通信)形式。

    用共享内存从服务器拷贝文件数据到客户端:


    共享内存基本API:

    #include<sys/ipc.h>

    #include<sys/shm.h>

    1.     int shmget(key_t key,size_t size,int shmflg);

    功能:用来创建共享内存

    key:是这个共享内存段的名字
    size:共享内存的大小
    shmflg:相当于权限位(如0666)
    返回值是共享内存段的标识码shmid,
    例如:shmid = shmget(0x1111, 128, 0666);
        //创建共享内存 , 相当于打开打开文件 
     //若共享内存存在 则使用   fopen()
     //若共享内存 不存在 则报错 -1

    shmid = shmget(0x1111, 128, 0666 | IPC_CREAT);
         //创建共享内存 , 相当于打开打开文件 
       //若共享内存存在 则使用   fopen()
      //若共享内存 不存在 则创建 


    shmid = shmget(0x1111, 128, 0666 | IPC_CREAT | IPC_EXCL);
     //创建共享内存 , 相当于打开文件 
    //若共享内存存在 则报错
    //若共享内存 不存在 则创建 
    //作用 IPC_EXCL判断存在不存在的标志  避免已经存在的文件 被覆盖

    2.  void *shmat(int shmid, const void *shmaddr, int shmflg);0xaa11

    功能:将共享内存段连接到进程地址空间

    shmaddr:指定连接的地址,因为内存地址是段页式管理,所以有可能传入的地址并不就是那一页的开头位置,所以传入一个地址,传出的仍然是一个地址,传出的是具体开始存储的地址。所以我们通常传入NULL,让编译器直接分配个合适的位置给我们。

    shmflg:它的两个取值可能是SHM_RND和SHM_RDONLY.

    例: void *p = shmat(shmid, NULL, 0);

    返回值:成功返回一个指针,指向共享内存第一个节,失败返回-1;


    3, int shmdt(const void *shmaddr);

    功能:将共享内存段与当前进程脱离,但并不等于删除共享内存段


    4,  int shmctl(int shmid,int cmd,struct shmid_ds *buf);

    功能:用于控制共享内存

    cmd:将要采取的动作

    1,IPC_STAT  把shmid_ds结构中的数据设置为共享内存的当前关联值

    2,IPC_SET    在进程有足够权限的前提下,把共享内存的当前关联值设置为shmid_ds数据结构中给出的值

    3,IPC_RMID  删除共享内存段

    buf: 指向一个保存着共享内存的模式状态和访问权限的数据结构

       例: shmctl(shmid, IPC_RMID, NULL);

       //删除共享内存

    若想要把旧的共享内存里面的内容保存下来,则传入一个地址,用来完成保存的功能


    为什么链接共享内存时要设计shmid,创建时要传入key:

    共享内存私有:





    Linux内核通过引用计数技术来管理共享内存生命周期







    展开全文
  • 共享单车、共享充电宝、共享雨伞,世间的共享有千万种,而我独爱共享内存。早期的共享内存,着重于强调把同一片内存,map到多个进程的虚拟地址空间(在相应进程找到一个VMA区域),以便于CPU可以在各个进程访问到这...
        

    共享单车、共享充电宝、共享雨伞,世间的共享有千万种,而我独爱共享内存。

    早期的共享内存,着重于强调把同一片内存,map到多个进程的虚拟地址空间(在相应进程找到一个VMA区域),以便于CPU可以在各个进程访问到这片内存。

    640?wx_fmt=png

    现阶段广泛应用于多媒体、Graphics领域的共享内存方式,某种意义上不再强调映射到进程虚拟地址空间的概念(那无非是为了让CPU访问),而更强调以某种“句柄”的形式,让大家知道某一片视频、图形图像数据的存在并可以借助此“句柄”来跨进程引用这片内存,让视频encoder、decoder、GPU等可以跨进程访问内存。所以不同进程用的加速硬件其实是不同的,他们更在乎的是可以通过一个handle拿到这片内存,而不再特别在乎CPU访问它的虚拟地址(当然仍然可以映射到进程的虚拟地址空间供CPU访问)。

    640?wx_fmt=png

    只要内存的拷贝(memcpy)仍然是一个占据内存带宽、CPU利用率的消耗大户存在,共享内存作为Linux进程间通信、计算机系统里各个不同硬件组件通信的最高效方法,都将持续繁荣。关于内存拷贝会大多程度地占据CPU利用率,这个可以最简单地尝试拷贝1080P,帧率每秒60的电影画面,我保证你的系统的CPU,蛋会疼地不行

    我早就想系统地写一篇综述Linux里面各种共享内存方式的文章了,但是一直被带娃这个事业牵绊,今日我决定顶着娃娃们的山呼海啸,也要写一篇文章不吐不快。

    共享内存的方式有很多种,目前主流的方式仍然有:

    640?wx_fmt=png

    共享内存的方式

    1.基于传统SYS V的共享内存;

    2.基于POSIX mmap文件映射实现共享内存;

    3.通过memfd_create()和fd跨进程共享实现共享内存;

    4.多媒体、图形领域广泛使用的基于dma-buf的共享内存。

    共享内存

    SYS V共享内存

    历史悠久、年代久远、API怪异,对应内核代码linux/ipc/shm.c,当你编译内核的时候不选择CONFIG_SYSVIPC,则不再具备此能力。

    你在Linux敲ipcs命令看到的share memory就是这种共享内存:

    640?wx_fmt=png

    下面写一个最简单的程序来看共享内存的写端sw.c:

    640?wx_fmt=png

    以及共享内存的读端sr.c:

    640?wx_fmt=png

    编译和准备运行:

    640?wx_fmt=png

    在此之前我们看一下系统的free:

    640?wx_fmt=png

    下面运行sw和sr:

    640?wx_fmt=png

    我们发现sr打印出来的和sw写进去的是一致的。这个时候我们再看下free:

    640?wx_fmt=png

    可以看到used显著增大了(711632 -> 715908), shared显著地增大了(2264 -> 6360),而cached这一列也显著地增大326604->330716。

    我们都知道cached这一列统计的是file-backed的文件的page cache的大小。理论上,共享内存属于匿名页,但是由于这里面有个非常特殊的tmpfs(/dev/shm指向/run/shm,/run/shm则mount为tmpfs):

    640?wx_fmt=png

    所以可以看出tmpfs的东西其实真的是有点含混:我们可以理解它为file-backed的匿名页(anonymous page),有点类似女声中的周深。前面我们反复强调,匿名页是没有文件背景的,这样当进行内存交换的时候,是与swap分区交换。磁盘文件系统里面的东西在内存的副本是file-backed的页面,所以不存在与swap分区交换的问题。但是tmpfs里面的东西,真的是在统计意义上统计到page cache了,但是它并没有真实的磁盘背景,这又和你访问磁盘文件系统里面的文件产生的page cache有本质的区别。所以,它是真地有那么一点misc的感觉,凡事都没有绝对,唯有变化本身是不变的。

    也可以通过ipcs找到新创建的SYS V共享内存:

    640?wx_fmt=png

    POSIX共享内存

    我对POSIX shm_open()、mmap () API系列的共享内存的喜爱,远远超过SYS V 100倍。原谅我就是一个懒惰的人,我就是讨厌ftok、shmget、shmat、shmdt这样的API。

    上面的程序如果用POSIX的写法,可以简化成写端psw.c:

    640?wx_fmt=png

    读端:

    640?wx_fmt=png

    编译和执行:

    640?wx_fmt=png

    这样我们会在/dev/shm/、/run/shm下面看到一个文件:

    640?wx_fmt=png

    坦白讲,mmap、munmap这样的API让我找到了回家的感觉,刚入行做Linux的时候,写好framebuffer驱动后,就是把/dev/fb0 mmap到用户空间来操作,所以mmap这样的 API,真的是特别亲切,像亲人一样。

    当然,如果你不喜欢shm_open()这个API,你也可以用常规的open来打开文件,然后进行mmap。关键的是mmap,wikipedia如是说:

    mmap

    In computing, mmap(2) is a POSIX-compliant Unix system call that maps files or devices into memory. It is a method of memory-mapped file I/O. It implements demand paging, because file contents are not read from disk directly and initially do not use physical RAM at all. The actual reads from disk are performed in a "lazy" manner, after a specific location is accessed. After the memory is no longer needed, it is important to munmap(2) the pointers to it. Protection information can be managed using mprotect(2), and special treatment can be enforced using madvise(2).

    POSIX的共享内存,仍然符合我们前面说的tmpfs的特点,在运行了sw,sr后,再运行psw和psr,我们发现free命令再次戏剧性变化:

    640?wx_fmt=png

    请将这个free命令的结果与前2次的free结果的各个字段进行对照:

    640?wx_fmt=png

    第3次比第2次的cached大了这么多?是因为我编写这篇文章边在访问磁盘里面的文件,当然POSIX的这个共享内存本身也导致cached增大了。

    memfd_create

    如果说POSIX的mmap让我找到回家的感觉,那么memfd_create()则是万般惊艳。见过这种API,才知道什么叫天生尤物——而且是尤物中的尤物,它完全属于那种让码农第一眼看到就会两眼充血,恨不得眼珠子夺眶而出贴到它身上去的那种API;一般人见到它第一次,都会忽略了它的长相,因为它的身材实在太火辣太抢眼了。

    先不要浮想联翩,在所有的所有开始之前,我们要先提一下跨进程分享fd(文件描述符,对应我们很多时候说的“句柄”)这个重要的概念。

    众所周知,Linux的fd属于一个进程级别的东西。进入每个进程的/proc/pid/fd可以看到它的fd的列表:

    640?wx_fmt=png

    这个进程的0,1,2和那个进程的0,1,2不是一回事。

    某年某月的某一天,人们发现,一个进程其实想访问另外一个进程的fd。当然,这只是目的不是手段。比如进程A有2个fd指向2片内存,如果进程B可以拿到这2个fd,其实就可以透过这2个fd访问到这2片内存。这个fd某种意义上充当了一个中间媒介的作用。有人说,那还不简单吗,如果进程A:

    fd = open();

    open()如果返回100,把这个100告诉进程B不就可以了吗,进程B访问这个100就可以了。这说明你还是没搞明白fd是一个进程内部的东西,是不能跨进程的概念。你的100和我的100,不是一个东西。这些基本的东西你搞不明白,你搞别的都是白搭。

    Linux提供一个特殊的方法,可以把一个进程的fd甩锅、踢皮球给另外一个进程(其实“甩锅”这个词用在这里不合适,因为“甩锅”是一种推卸,而fd的传递是一种分享)。我特码一直想把我的bug甩(分)锅(享)出去,却发现总是被人把bug甩锅过来。

    那么如何甩(分)锅(享)fd呢?

    欲知后事如何,请听下回分解~~~

    640?wx_fmt=png


    更多精彩,尽在"Linux阅码场",扫描下方二维码关注

    640?wx_fmt=png

    你的随手转发或点个在看是对我们最大的支持!

    展开全文
  • linux内核支持多种共享内存方式,如mmap内存映射,Posix共享内存,以system V共享内存。当内核空间和用户空间存在大量数据交互时,共享内存映射就成了这种情况下的不二选择。它能够最大限度的降低内核空间和用户空间...

    linux内核支持多种共享内存方式,如mmap内存映射,Posix共享内存,以system V共享内存。当内核空间和用户空间存在大量数据交互时,共享内存映射就成了这种情况下的不二选择。它能够最大限度的降低内核空间和用户空间之间的数据拷贝,从而大大提高系统的性能。

    共享内存是最有用,也是最快的IPC方式。两个不同进程A、B共享内存时,同一块物理内存被映射到进程A、B各自的进程地址空间。进程A可以即时看到进程B对共享内存中数据的更新,反之亦然。由于多个进程共享同一块内存区域,必然需要某种同步机制,互斥锁和信号量都可以。

    内存映射,简而言之就是将用户空间的一段内存区域(即进程地址空间的内存映射段,其位于堆空间和栈空间之间)映射到内核空间,映射成功后,用户对这段内存区域的修改可以直接反映到内核空间,同样,内核空间对这段区域的修改也直接反映用户空间,那么对于内核空间和用户空间两者之间需要大量数据传输等操作的话效率是非常高的。对于Posix共享内存和system V共享内存一样,在地址空间处于内存映射段,物理内存处于内核区。因此,这三种方式都不需要内核区与用户区进行数据的交换,效率更高,通过指针的方式可以直接对内存进行访问。对于大数据的内存访问,一般来说在Linux系统中采用内存映射和共享内存是最好的方式,这样对于应用层来说,可以很方便的访问到内核的空间。

    mmap内存映射

    mmap内存映射的方式分为两种:文件映射(一般文件或者/dev/zero文件)和匿名映射。文件映射,是指该地址空间(内存映射段)的内容来自于一个文件;而匿名映射地址空间背后什么靠山都没有。进程的代码段来自于镜像,采用文件映射方式;而栈,堆,.bss段,数据段均是匿名映射。

    下图是文件映射的示意图(映射文件的一部分):

    off为偏移大小,len为映射区的大小。

    mmap函数是unix和类unix下的系统调用,其系统调用接口为:void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);   mmap内存映射的作用有二:1.用于共享内存,完成IPC;2.提供了不同于一般访问文件的方式,如系统函数(read和write等)、C库函数(printf、scanf等),由于其不需要内核空间与用户空间的数据拷贝,因此效率会更高。使得访问文件类似于直接访问内存一样,直接用指针就可以操作文件。Posixsystem V的共享内存IPC则纯粹用于共享目的,当然mmap实现共享内存也是其主要应用之一。

    mmap内存映射并不分配空间,只是将文件映射到调用进程的地址空间里(但是会占掉你的 virutal memory),然后你就可以用memcpy等操作写文件,而不用write了。写完后,内存中的内容并不会立即更新到文件中,而是有一段时间的延迟,你可以调用msync来显式同步一下, 这样你所写的内容就能立即保存到文件里了。不过通过mmap来写文件这种方式没办法增加文件的长度,因为要映射的长度在调用mmap的时候就决定了。

    在内存映射的过程中,并没有实际的数据拷贝,文件没有被载入内存,只是逻辑上被放入了地址空间的内存映射段。在用指针实际访问的时候,逻辑地址加上基地址形成的线性地址经过MMU映射成为物理地址,此时会检测到访问的文件不在内存,从而通过缺页中断请求的方式,才将其调入内存,并同时修改页表和快表,此时才真正调入到内存。即MMU完成了地址的变换(变换后的信息存储在PCB中)、缺页中断、调页请求等。缺页中断的中断响应函数会在swap中寻找相对应的页面,如果找不到(也就是该文件从来没有被读入内存的情况),则会通过mmap建立的映射关系,从硬盘上将文件读取到物理内存中。如果在拷贝数据时,发现物理内存不够用,则会通过虚拟内存机制(swap)将暂时不用的物理页面交换到硬盘上。

    比较:mmapC库函数、系统函数、管道和消息队列

    用户进程通过系统调用访问系统资源(如访问文件)时需要切换到内核态,而这对应一些特殊的堆栈和内存环境,必须在系统调用前建立好。在系统调用后,CPU会从内核态转换到用户态,而堆栈又必须恢复成用户进程的上下文,这种切换会消耗大量的系统时间。在用户态,不仅仅是系统资源,位于其它进程空间的资源都是看不到的(透明的),因此在切换到用户态时,需要将系统调用访问的资源拷贝到用户空间,才能被用户空间进行操作,用户态是没有权限对内核进行操作的。

    read、write等系统函数访问文件时,都是先将外部设备上的数据读到内核缓冲区,然后将内核的数据交到用户缓冲区,然后用户进程就可以通过用户缓冲区来使用这些数据了。printf等C库函数一样,它们的唯一区别就是,C库函数有自己维护的I/O缓冲区(8KB),而系统函数需要自己指定缓冲区buff。C库函数对文件的访问,最终也是通过read和write等系统函数来完成的。但由于其I/O缓冲区(无缓冲、行缓冲和全缓冲)比较大,因此较少了内核与用户的交互次数,从而一般比系统函数访问速度会更快,但是系统函数可以通过指定buff的大小大于I/O缓冲区的大小,使其效率比C库函数更高,它们的原理一样的。 综上,内核缓冲区是为了减少操作磁盘等外部设备的次数,缓解CPU的速度与外部设备速度之间的不匹配;而I/O缓冲区是为了减少系统调用的次数。

    采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝。对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝(读文件read、再write到管道一端、再从管道另一端read、最后再write到外部文件),而共享内存则只拷贝两次数据。一次从输入文件到共享内存区,另一次从共享内存区到输出文件。实际上,进程之间在共享内存时,并不总是读写少量数据后就解除映射,有新的通信时,再重新建立共享内存区域。而是保持共享区域,直到通信完毕为止,这样,数据内容一直保存在共享内存中,并没有写回文件。共享内存中的内容往往是在解除映射时才写回文件的。因此,采用共享内存的通信方式效率是非常高的。

    内核将硬盘文件的内容直接映射到内存, 任何应用程序都可通过Linux的mmap()系统调用请求这种映射。内存映射是一种方便高效的文件I/O方式, 因而被用于装载动态共享库。如C标准库函数(fread、fwrite、fopen等)和Linux系统I/O函数,它们都是动态库函数,其中C标准库函数都被封装在了/lib/libc.so库文件中,都是二进制文件。这些动态库函数都是与位置无关的代码,即每次被加载进入内存映射区时的位置都是不一样的,因此使用的是其本身的逻辑地址,经过变换成线性地址(虚拟地址),然后再映射到内存。而静态库不一样,由于静态库被链接到可执行文件中,因此其位于代码段,每次在地址空间中的位置都是固定的。

    system V共享内存

    共享内存就是多个进程的地址空间映射到同一个物理内存,多个进程都能看到这块物理内存,共享内存可以提供给服务器进程和客户进程之间进行通信,不需要进行数据的复制,所以速度最快。

    共享内存操作需要的函数:

    1.我们需要利用ftok函数生成key标识符。

    key_t ftok(const char *pathname,int proj_id);

    2.使用shmgt函数,创建一个共享内存块,返回这个共享内存块的标识符shmid。

    int shmget(key_t key,size_t size,int shmflg);

    size是需要申请的共享内存的大小,需要注意的是,操作系统为你提供的大小的时候是按页来提供,所以size为4k的整数倍;shmflg:如果要创建新的共享内存,那么就使用IPC_CREAT,IPC_EXCL,如果是已经存在的,那么只需要使用IPC_CREAT。

    3.用shmat挂接共享内存(将进程地址空间挂接到共享内存,共享内存是物理空间,可以有多个挂接)

    void *shmat(int shmid,const void *shmaddr, int shmflg);

    shmid是挂接的进程号;shmaddr置为NULL,让系统选择一个合适的地址空间进行挂接;shmflg表示什么方式进行挂接,一般都是取0;函数返回各个进程挂接的虚拟的地址空间。

    4.用shmdt去挂接。

    int shmdt(const void *shmaddr);

    5.用shmctl销毁共享内存

    int shmctl(int shmid,int cmd,struct shmid_ds *buf);

    cmd取IPC_RMID表示删除这块共享内存;buf一般设置为NULL,不关心这个东西,消息队列中也有这么一个类似的结构体也是设置为NULL。

    共享内存与mmap内存映射的区别

    首先说明相同点:都可以进行进程之间的通信。

    mmap还可以提供非文件进行访问的操作,访问文件就像访问内存一样,可以用指针直接对文件进行操作,但是速度还是不一样,毕竟mmap最终还是访问的是磁盘文件。

    mmapshm

    1.mmap是在磁盘上建立一个文件,每个进程地址空间中开辟出一块空间进行映射。而对于shm而言,shm每个进程最终会映射到同一块物理内存。shm保存在物理内存,这样读写的速度要比磁盘要快,但是存储量不是特别大。

    2.相对于shm来说,mmap更加简单,调用更加方便,所以这也是大家都喜欢用的原因。

    3.另外mmap有一个好处是当机器重启,因为mmap把文件保存在磁盘上,这个文件还保存了操作系统同步的映像,所以mmap不会丢失,但是shmget就会丢失。

    展开全文
  • 共享内存及其用mmap实现共享内存

    千次阅读 2016-08-01 00:32:49
    一、什么是共享内存顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存。共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常安排为同一段物理内存。...
  • linux 共享内存与nginx共享内存

    千次阅读 2014-03-12 13:37:04
    共享内存的实现分为两个步骤: 一、 创建共享内存,使用shmget函数。 二、 映射共享内存,将这段创建的共享内存映射到具体的进程空间去,使用shmat函数。 创建共享内存 int shmget(key_t key ,int size,int ...
  • Java 共享内存

    千次阅读 2019-06-11 20:00:08
    对UNIX系统来说,共享内存分为一般共享内存和映像文件共享内存两种,对windows实际上只有映像文件共享内存一种。所以java应用中也是只能创建映像文件共享内存。使用共享内存,有如下几个特点: 1、可以被多个进程...
  • Linux共享内存和Qt共享内存SharedMemory简介Linux共享内存使用Qt共享内存SharedMemory使用 简介 Linux系统下进程通信的方式有很多: 管道(pipe) 命名管道(FIFO) 内存映射(mapped memeory) 消息队列(message queue) ...
  • nginx共享内存共享内存的实现

    千次阅读 2014-07-15 23:56:30
    nginx中, 作者为我们提供了方便共享内存的使用的接口,关于共享内存的使用在我之前的文章中有介绍。这次我们来研究一下nginx是如何实现的。 我们知道,如果我们的模块中要使用一个共享内存,需要调用ngx_shared_...
  • 共享单车、共享充电宝、共享雨伞,世间的共享有千万种,而我独爱共享内存。早期的共享内存,着重于强调把同一片内存,map到多个进程的虚拟地址空间(在相应进程找到一个VMA区域),以便于CPU...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 73,267
精华内容 29,306
关键字:

共享内存