共享内存

python共享内存

萝らか妹 提交于 2020-02-05 01:55:36
https://docs.python.org/zh-cn/3/library/multiprocessing.html 共享内存 可以使用 Value 或 Array 将数据存储在共享内存映射中。例如,以下代码: from multiprocessing import Process, Value, Array def f(n, a): n.value = 3.1415927 for i in range(len(a)): a[i] = -a[i] if __name__ == '__main__': num = Value('d', 0.0) arr = Array('i', range(10)) p = Process(target=f, args=(num, arr)) p.start() p.join() print(num.value) print(arr[:])    来源: https://www.cnblogs.com/kekeoutlook/p/12262304.html

Go_channel

99封情书 提交于 2020-02-03 06:51:01
通道可以被认为是Goroutines通信的管道。类似于管道中的水从一端到另一端的流动,数据可以从一端发送到另一端,通过通道接收。 在前面讲Go语言的并发时候,我们就说过,当多个Goroutine想实现共享数据的时候,虽然也提供了传统的同步机制,但是Go语言强烈建议的是使用Channel通道来实现Goroutines之间的通信。 “不要通过共享内存来通信,而应该通过通信来共享内存” 这是一句风靡golang社区的经典语 Go语言中,要传递某个数据给另一个goroutine(协程),可以把这个数据封装成一个对象,然后把这个对象的指针传入某个channel中,另外一个goroutine从这个channel中读出这个指针,并处理其指向的内存对象。Go从语言层面保证同一个时间只有一个goroutine能够访问channel里面的数据,为开发者提供了一种优雅简单的工具,所以Go的做法就是使用channel来通信,通过通信来传递内存数据,使得内存数据在不同的goroutine中传递,而不是使用共享内存来通信。 一、 什么是通道 1.1 通道的概念 通道是什么,通道就是goroutine之间的通道。它可以让goroutine之间相互通信。 每个通道都有与其相关的类型。该类型是通道允许传输的数据类型。(通道的零值为nil。nil通道没有任何用处,因此通道必须使用类似于map和切片的方法来定义。) 1

ROS系统节点间的内存共享

痞子三分冷 提交于 2020-01-31 01:08:38
ROS系统节点间的内存共享 为什么要用内存共享? 在C++中怎么共享内存? 写进程 读进程 将上述代码移植进ROS 创建writeshmInRos.cpp 创建readshmInRos.cpp 为什么要用内存共享? 答案是ROS提供的服务或者话题都是通过网络来实现的。照顾到ROS节点可能架设在不同的硬件上这一点,这样做更具普遍性,但对于在同一台设备的两个节点间传输数据是非常不友好的。因为其既没必要性又浪费大量资源,且效率低下,容易造成网络堵塞,延时严重。 那么怎么改善最好呢,自然是进程间的内存共享。我们直接让两个节点共享一片物理内存,在里面做一个队列数据结构,一个往里面写,一个去里面读。 下面我们就来实现这一功能。跟上篇文章一样,我们先实现纯净的Linux C++版本,然后再把代码移植到ROS的节点中。 在C++中怎么共享内存? 实现Linux进程间的内存共享,主要参考 这篇文章 。 写进程 “写”进程,流程如下: 获得key, ftok() 使用key来创建一个共享内存 shmget() 映射共享内存(得到虚拟地址), shmat() 使用共享内存, 往共享内存中写入数据 解除映射 shmdt() 如果共享内存不再使用,可以使用shmctl()销毁共享内存 代码如下: # include <stdio.h> # include <unistd.h> # include

进程间通信

与世无争的帅哥 提交于 2020-01-30 11:34:38
进程间通信原因 因为每一个进程都是拥有一个独立的虚拟地址空间的,促使进程独立,导致了进程之间需要协作。 进程间通信分为 数据传输-----管道,消息队列 数据共享-----共享内存 进程控制-----信号量 首先先谈谈管道和共享内存 管道 ---匿名管道,命名管道 本质:管道其实就是一块内存,是内核当中的缓冲区 匿名管道---没有标识 特性: 具有亲缘关系的进程间通信 半双工,数据只能有一个流向 提供字节流服务 自带同步与互斥功能 生命周期随进程,进程终止,生命周期消失 如果管道为空,则读阻塞 如果管道为满,则写阻塞 如果管道的读端被关闭,则写端往管道当中写数据的时候,会造成管道破裂,并且导致进程收到SIGPIPE信号,从而进程终止 如果管道的写端被关闭掉了,则读端读完管道的数据之后,read不会陷入阻塞状态,而是返回。执行代码剩下的正常流程 管道大小PIPE_SIZE:64K,PIPE_BUG:4K 如果写入的数据大于PIPE_BUG的话,则不保证写入数据的原子性 原子性:当前操作不被打断,换句话说,在管道的读写操作是不可以被打断的 临界资源:同一时间,当前资源只能被一个进程所访问 互斥:同一时间,保证只能有一个进程访问临界资源 同步:保证临界资源访问的合理性 创建一个管道(亲缘关系的进程中使用) int pipe(int pipefd[2]); pipefd[0]

进程间通信小结

瘦欲@ 提交于 2020-01-29 02:04:28
进程间通信: 1、进程间的数据共享: 管道、 消息队列、 共享内存、 Unix域套接字 易用性: 消息队列 > Unix域套接字 > 管道 > 共享内存(经常与信号量一起用) 效 率: 共享内存 > Unix域套接字 > 管道 > 消息队列 常 用: 共享内存、Unix域套接字 2、异步通信 信号 3、同步与互斥(做资源保护) 信号量 来源: https://www.cnblogs.com/y4247464/p/12239464.html

Linux进程间通信

丶灬走出姿态 提交于 2020-01-28 04:49:13
进程间数据通信需要使用特殊手段,如信号量、队列、共享内存等,因为彼此之间获取不到全局变量。 线程间通信比较简单,直接使用全局变量就行。 目录 一、队列 1.创建新消息队列或取得已存在消息队列 2.向队列读/写消息 3.设置消息队列属性 4.例程 二、共享内存 1.生成键值 2.创建共享存储空间 3.获取第一个可用共享内存空间的地址 4.例程 一、队列 这篇CSDN博客讲述的队列通信验证是正确的。20191209 这篇文章讲得也很详细 1.创建新消息队列或取得已存在消息队列 原型: int msgget ( key_t key , int msgflg ) ; 参数: key:可以认为是一个端口号,也可以由函数ftok生成。 msgflg:IPC_CREAT值,若没有该队列,则创建一个并返回新标识符;若已存在,则返回原标识符。   IPC_EXCL值,若没有该队列,则返回 - 1 ;若已存在,则返回 0 。 2.向队列读/写消息 msgrcv从队列中取用消息:ssize_t msgrcv ( int msqid , void * msgp , size_t msgsz , long msgtyp , int msgflg ) ; msgsnd将数据放到消息队列中: int msgsnd ( int msqid , const void * msgp , size_t msgsz ,

Linux下进程通信及/异常处理

北城以北 提交于 2020-01-27 16:46:44
在使用共享内存的时,有时候程序异常结束,导致共享内存没有被释放,进而导致程序重新运行无法使用共享内存通信。 提示信息为 file exits ; 这时 我们 销毁共享内存 再重新运行就 OK 不用修改coredump 文件 ,也不要去gdb, bt查看了 。 ipcs 或者 ipcs-m 命令 显示当前的 system V 解决办法: 1.ipcs 或者 ipcs-m 命令 查看当前的 system V 2.在终端输入命令 ipcrm -m shmid(获取到的shmid值)即可删除共享内存 来 一波代码 comm.hpp: # include <stdio.h> # include <sys/types.h> # include <sys/ipc.h> # include <sys/shm.h> # define PATHNAME "." # define PROJ_ID 0x6666 int createShm ( int size ) ; //create int destroyShm ( int shmid ) ; //destroy int getShm ( int size ) ; //get //创建一段共享内存,并获取其 标识码 static int commShm ( int size , int flags ) { key_t key = ftok ( "."

linux c 内存共享

折月煮酒 提交于 2020-01-27 13:04:57
一、什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存。共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常安排为同一段物理内存。进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言函数malloc()分配的内存一样。而如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程。 特别提醒:共享内存并未提供同步机制,也就是说,在第一个进程结束对共享内存的写操作之前,并无自动机制可以阻止第二个进程开始对它进行读取。所以我们通常需要用其他的机制来同步对共享内存的访问 二、共享内存的使得 与信号量一样,在Linux中也提供了一组函数接口用于使用共享内存,而且使用共享共存的接口还与信号量的非常相似,而且比使用信号量的接口来得简单。它们声明在头文件 sys/shm.h 中。 1、shmget()函数 该函数用来创建共享内存,它的原型为: int shmget(key_t key, size_t size, int shmflg); 第一个参数,与信号量的semget函数一样,程序需要提供一个参数key(非0整数),它有效地为共享内存段命名,shmget()函数成功时返回一个与key相关的共享内存标识符(非负整数)

Volatile作用

大兔子大兔子 提交于 2020-01-25 21:38:06
volatile的用处: 在JDK1.2之前,Java内存模型总是从主存(共享内存)中读取变量值,是不需要进行特别注意的。 在当前Java内存模型下,线程可以把变量保存在本地内存,如寄存器中,而不是直接在主存中进行读写。这就造成了一个线程在主存中修改了一个变量的值,而另一个线程还在使用它在寄存器中的变量值的拷贝,造成了了数据不一致。 为了解决这个问题,我们就需要把该变量声明为volatile,这就指示JVM,这个变量是不稳定的,每次使用他都要去主存中读取,而不是本地内存,一般说来,多任务环境下,各任务间共享的变量,都应该使用volatile进行修饰。 volatile修饰的变量,在被每次线程访问时,都强迫从共享内存中重读该变量的值。而且当该变量变化时,都强迫线程将变化的值写到共享内存中,这样在任何时刻,两个不同的线程总是看到该变量的同一个值。 Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才将私有拷贝与共享内存中的原始值进行比较。 这样当多个线程同时与某个对象交互时,就必须注意到要让线程及时的得到共享成员变量的变化。而volatile关键字就是提示JVM:对于这个成员变量,不能保存它的私有拷贝,而应直接与共享成员变量交互。 volatile是一种稍弱的同步机制,在访问volatile变量时不会执行加锁操作

4.Java内存模型JMM

懵懂的女人 提交于 2020-01-25 03:31:16
文章目录 1. 线程通信 2. 线程同步 3. 内存模型 3.1. 内存模型分类 3.2. JMM 的内存可见性保证 JMM 属于语言级的内存模型,它确保在不同的编译器和不同的处理器平台之上,通过禁止特定类型的编译器重排序和处理器重排序,为程序员提供一致的内存可见性保证. 在并发编程中,需要处理两个关键问题:线程之间如何通信及线程之间如何同步. 1. 线程通信 通信是指线程之间以何种机制来交换信息。在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递 共享内存 的并发模型里,线程之间共享程序的公共状态,通过写-读内存中的公共状态进行隐式通信 消息传递 的并发模型里,线程之间没有公共状态,线程之间必须通过发送消息来显式进行通信 2. 线程同步 即当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作, 其他线程才能对该内存地址进行操作 共享内存 并发模型里,同步是显式进行的。程序员必须显式指定某个方法或某段代码需要在线程之间互斥执行。 消息传递 并发模型里,由于消息的发送必须在消息的接收之前,因此同步是隐式进行的 Java 的并发采用的是 共享内存 模型,Java 线程之间的通信总是隐式进行,整个通信过程对程序员完全透明 3. 内存模型 共享变量 在 Java 中,所有实例域、静态域和数组元素都存储在堆内存中,堆内存在线程之间共享(本章用