共享内存

进程间的通信方式——共享内存

ぐ巨炮叔叔 提交于 2019-11-30 05:49:01
共享内存指在多处理器的计算机系统中,可以被不同中央处理器(CPU)访问的大容量内存。由于多个CPU需要快速访问存储器,这样就要对存储器进行缓存(Cache)。 1.共享内存 共享内存是进程间通信中最简单的方式之一。共享内存允许两个或者多个进程访问同一块内存,就如同malloc()函数向不同进程返回了指向一个物理内存区域的指针。当一个进程改变了这块地址中的内容的时候,其他进程都会察觉到这个更改。 共享内存的特点: 1.共享内存是进程间共享数据的一种最快的方法。一个进程向共享内存的内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容。 2.使用共享内存要注意的是多个进程之间对一个给定存储区访问的互斥。若一个进程正在给共享内存区写数据,则在它做完这一步操作前,别的进程不应当去读、写这些数据。 2.共享内存模型 要用一块共享内存,进程必须首先分配它。随后需要访问这个共享内存块的每一个进程都必须将这个共享内存绑定到自己的地址空间中。当完成通信之后,所有进程都将脱离共享内存,并且由一个进程释放该共享内存块。理解 Linux 系统内存模型可以有助于解释这个绑定的过程。在 Linux 系统中,每个进程的虚拟内存是被分为许多页面的。这些内存页面中包含了实际的数据。每个进程都会维护一个从内存地址到虚拟内存页面之间的映射关系。尽管每个进程都有自己的内存地址

一种以动态库的方式使用资源表的方案

喜夏-厌秋 提交于 2019-11-30 02:17:37
这段时间研究了一下资源表的优化方案,算是有了一些成果,在此记录下来。 先交代一下背景吧:我们的服务器把资源表放在共享内存上。这么做的原因主要是,进程core掉后再拉起时不需要重新再构建一遍资源表(构建资源表主要就是构建索引查询的数据结构,比如构建一个哈希表用于根据HeroID查询英雄配置这种)。然后,考虑到同一个机器上可能部署多个进程,于是自然就想到,能否有一种机制能够让一个机器上的多个进程共享同一块资源表的内存? 一个比较直观的想法就是,让多个进程挂在同一块资源表共享内存。这样做确实是可以达到内存共享的目的,但是需要考虑资源表reload的情况。reload时会对这块内存做写操作,而我们知道,一写多读是会有并发问题。因此这种方案还需要再引入一种机制来处理并发问题。常见的比如是双缓冲区,构建好后再一次性切换到新的资源表内存上。了解到了一些项目组确实也是这么做的,具体就不细说了。 而我想到的方法是这样的:使用代码生成技术,将资源表完全的导成c++的代码。所有用到于查询的数据结构都是通过自动代码生成的,并且在编译期就被静态构建好了。进程运行时直接载入这块内存即可,不需要像以前那样在起服时跑资源表构建的流程。因此,这块内存也不需要再手动放共享内存上了。core之后再拉起进程,最多就是资源表的内存被卸载了,并且会到下次用到时通过触发缺页中断被再次载入进内存。为了做同一机器上的内存共享

进程间通信(8) - 共享内存(posix)

天大地大妈咪最大 提交于 2019-11-29 22:11:28
1.前言 本篇文章的所有例子,基于RHEL6.5平台(linux kernal: 2.6.32-431.el6.i686)。 2.共享内存介绍 前面所讲述的Linux下面的各种进程间通信方式,例如:pipe(管道),FIFO(命名管道),message queue(消息队列),它们的共同点都是通过内核来进行通信(假设posix消息队列也是在内核中实现的,因为posix标准没有规定它的具体实现方式)。向pipe,fifo,message queue写入数据时,需要把数据从用户空间(用户进程)复制到内核,而从这些IPC读取数据时,又需要把数据从内核复制到用户空间。因此,所有的这些IPC方式,都需要在内核与用户进程之间进行2次数据复制,即进程间的通信必须通过内核来传递,如下图所示: 通过内核进行进程间通信(IPC) 共享内存也是一种 IPC ,它是目前最快的IPC,它的使用方式是将同一个内存区映射到共享它的不同进程的地址空间中,这样这些进程间的通信就不再需要通过内核,只需对该共享的内存区域进程操作就可以了。和其他 IPC 不同的是,共享内存的使用需要用户自己进行同步操作。下图是共享内存区 IPC 的通信: 3.映射函数mmap 每个进程都有自己的虚拟地址空间,我们知道除了堆中的虚拟内存我们可以由程序员灵活分配和释放,其他区域的虚拟内存都由系统控制

C++11的智能指针总结

五迷三道 提交于 2019-11-29 19:30:57
到现在为止遇到了几种智能指针 shared_ptr 特点:可以自动销毁,并且可以多个指针指向同一块动态内存,内部有一个计数器,等到计数器为零就会自动销毁 weak_ptr 特点:是shared_ptr指针的附属,weak_ptr指向shared_ptr的区域,但并不会增加shared_ptr的计数器值,而且也不可以直接使用,需要lock(),提升为shared_ptr才可以使用。 scope_ptr 特点:也可以自动释放,但是不能和其他指针共享内存,也就是一块共享内存只能有一个scope_ptr指针,因为scope_ptr在销毁时是直接销毁这个指针指向的动态内存,如果有其他指针一起指向,那么其他指针就没有用了。 并且这个指针不能进行移动和复制操作的,可以交换 unique_ptr:也可以自动释放,但是不能和其他指针共享内存,也就是一块共享内存只能有一个scope_ptr指针 但是这个指针可以移动,不能复制 unique_ptr<TEST> p2(p1.release()); 例如上面程序就是把p1指向的内容转给了p2,然后p1指向NULL 来源: https://blog.csdn.net/qq_34489443/article/details/100898623

Posix信号量

孤街浪徒 提交于 2019-11-29 15:39:37
目录 1. Posix IPC 概述 IPC名字 创建与打开IPC 读写权限与创建标志 用户访问权限 IPC对象的持续性 2. 信号量概述 信号量定义及分类 信号量操作 信号量、互斥锁和条件变量的差异 3. Posix有名信号量 创建和打开 关闭和删除 等待和挂出 获取信号量的值 4. Posix无名信号量 5. Posix信号量限制 1. Posix IPC 概述 以下三种类型的IPC合称为Posix IPC: Posix信号量 Posix消息队列 Posix共享内存 Posix IPC在访问它们的函数和描述它们的信息上有一些类似点,主要包括: IPC名字 创建或打开时指定的读写权限、创建标志以及用户访问权限 下表汇总了所有Posix IPC函数。 信号量 消息队列 共享内存 头文件 semaphore.h mqueue.h sys/mman.h 创建、打开或删除IPC的函数 sem_open sem_close sem_unlink sem_init sem_destroy mq_open mq_close mq_unlink shm_open shm_unlink 控制IPC操作的函数 mq_getattr mq_setattr ftruncate fstat IPC操作函数 sem_wait sem_trywait sem_post sem_getvalue mq_send

进程线程等学习笔记

柔情痞子 提交于 2019-11-29 12:19:56
总共分为12部分分别是:进程、线程、消息队列、信号量集、共享内存、PGSQL编程、MYSQL编程、网络编程、文件访问、标准I/O、系统数据文件和信息、信号 (一) 进程 1. 进程ID为0的进程通常是调度进程,常常被称为交换进程 进程ID为1的进程通常是init进程,在自举过程结束时由内核调用 进程ID为2的进程页守护进程,负责支持虚拟存储系统的分页操作 2. pid_t getpid( void ); 返回值:调用进程的进程ID #include <unistd.h> 3. pid_t getppid( void ); 返回值:调用进程的父进程ID 4. uid_t getuid( void ); 返回值:调用进程的实际用户ID 5. uid_t geteuid( void ); 返回值:调用进程的有效用户ID 6. gid_t getgid( void ); 返回值:调用进程的实际组ID 7. gid_t getegid( void ); 返回值:调用进程的有效组ID 8. pid_t fork( void );创建子进程,返回值:子进程返回0,父进程返回子进程ID,出错-1 9. #include<sys/wait.h> pid_t wait(int *statloc);//statloc 保存进程终止状态的指针 10. #include<sys/wait.h>pid_t

linux各种IPC机制

≯℡__Kan透↙ 提交于 2019-11-29 11:06:08
linux各种IPC机制   docker中的资源隔离,一种就是IPC的隔离。IPC是进程间通信。 下面的文章转载自https://blog.csdn.net/yyq_9623/article/details/78794775 原帖发表在IBM的developerworks网站上,是一个系列的文章,作者郑彦兴,通过讲解和例子演示了Linux中几种IPC的使用方式,我觉得很好,在这里做一个保留,能看完的话Linux IPC的基础是没有问题的了。 一)Linux环境进程间通信(一)管道及有名管道 http://www.ibm.com/developerworks/cn/linux/l-ipc/part1/ 二)Linux环境进程间通信(二): 信号 上: http://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index1.html 下: http://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index2.html 三)Linux环境进程间通信(三)消息队列 http://www.ibm.com/developerworks/cn/linux/l-ipc/part3/ 四)Linux环境进程间通信(四)信号灯 http://www.ibm.com/developerworks

进程间通讯IPC的几种方式的优缺点总结

走远了吗. 提交于 2019-11-29 02:42:14
Linux进程间的通讯 Unix发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间通信方面的侧重点有所不同。前者对Unix早期的进程间通信手段进行了系统的改进和扩充,形成了“system V IPC”,通信进程局限在单个计算机内;后者则跳过了该限制,形成了基于套接口(socket)的进程间通信机制。Linux则把两者继承了下来,如图示: 管道 管道的通信介质是文件,这种文件通常称为管道文件,两个进程利用管道文件进行通信时,一个进程为写进程,另一个进程为读进程。写进程通过写端(发送端)往管道文件中写入信息;读进程通过读端(接收端)从管道文件中读取信息。两个进程协调不断地进行写、读,便会构成双方通过管道传递信息的流水线。 匿名管道pipe 匿名管道是半双工的,数据只能单向通信;需要双方通信时,需要建立起两个管道;只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程)。 命名管道fifo 不同于匿名管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(能够访问该路径的进程以及FIFO的创建进程之间),因此,通过FIFO不相关的进程也能交换数据。值得注意的是,FIFO严格遵循先进先出(first in first

python多进程通信实例分析

会有一股神秘感。 提交于 2019-11-29 02:31:28
操作系统会为每一个创建的进程分配一个独立的地址空间,不同进程的地址空间是完全隔离的,因此如果不加其他的措施,他们完全感觉不到彼此的存在。那么进程之间怎么进行通信?他们之间的关联是怎样的?实现原理是什么?本文就来借助Python简单的聊一下进程之间的通信?还是那句话,原理是相同的,希望能透过具体的例子来体会一下本质的东西。 下面尽量以简单的方式介绍一下每一类通信方式,具体的细节可以参照文档使用; 1. 管道 先来看一下最简单、古老的一种IPC:管道。通常指的是无名管道,本质上可以看做一种文件,只存在于内存当中,不会存盘。不同进程通过系统提供的接口来向管道中读取或者写入数据。 也就是说我们通过这样一个中间介质为进程提供交流的方式。无名管道的局限在于一般只用于有直接关联关系的父子进程。下面通过一个简单的例子来看一下其用法。 from multiprocessing import Process, Pipe def pstart(pname, conn): conn.send("Data@subprocess") print(conn.recv()) # Data@parentprocess if __name__ == '__main__': conn1, conn2 = Pipe(True) sub_proc = Process(target=pstart, args=(

POSIX共享内存

只愿长相守 提交于 2019-11-29 01:59:12
前言 几种进程间的通信方式:管道,FIFO,消息队列,他们的共同特点就是通过内核来进行通信(假设POSIX消息队列也是在内核中实现的,因为POSIX标准并没有限定它的实现方式)。向管道,FIFO,消息队列写入数据需要把数据从进程复制到内核,从这些IPC读取数据的时候又需要把数据从内核复制到进程。所以这种IPC方式往往需要2次在进程和内核之间进行数据的复制,即进程间的通信必须借助内核来传递。如下图所示: 共享内存也是一种IPC,它是目前可用IPC中最快的,它是使用方式是将同一个内存区映射到共享它的不同进程的地址空间中,这样这些进程间的通信就不再需要通过内核,只需对该共享的内存区域进程操作就可以了,和其他IPC不同的是,共享内存的使用 需要用户自己进行同步操作 。下图是共享内存区IPC的通信: mmap系列函数简介 mmap函数主要的功能就是将文件或设备映射到调用进程的地址空间中,当使用mmap映射文件到进程后,就可以直接操作这段虚拟地址进行文件的读写等操作,不必再调用read,write等系统调用。在很大程度上提高了系统的效率和代码的简洁性。 使用mmap函数的主要目的是: 对普通文件提供内存映射I/O,可以提供无亲缘进程间的通信; 提供匿名内存映射,以供亲缘进程间进行通信。 对shm_open创建的POSIX共享内存区对象进程内存映射,以供无亲缘进程间进行通信。