精华内容
下载资源
问答
  • 内存共享
    千次阅读
    2018-11-28 16:13:49

    上一篇文章我们介绍了怎么在ROS中应用LCM与外部进行通信。本篇我们回到ROS的内部,看看如何实现ROS节点间的内存共享,以实现更加快速的内部通信。

    首先,我们需要清楚为什么要用内存共享?

    答案是ROS提供的服务或者话题都是通过网络来实现的。这样做虽然更具普遍性,照顾到ROS节点可能架设在不同的硬件上这一点,然对于在同一台设备的两个节点间传输数据是非常不友好的。因为其既没必要性又浪费大量资源,且效率低下,容易造成网络堵塞,延时严重。

    那么怎么改善最好呢,自然是进程间的内存共享。我们直接让两个节点共享一片物理内存,在里面做一个队列数据结构,一个往里面写,一个去里面读。

    下面我们就来实现这一功能。跟上篇文章一样,我们先实现纯净的Linux C++版本,然后再把代码移植到ROS的节点中。

    实现Linux进程间的内存共享,主要参考这篇文章(因为写的很好,运行顺利,这部分只做了一点点修改,其他照抄,见谅见谅):

    “写”进程,流程如下:

    1) 获得key, ftok()

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

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

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

    5) 解除映射 shmdt()

    6) 如果共

    更多相关内容
  • 运用windwosAPI共享内存的使用实例
  • python进程通信之内存共享

    千次阅读 2022-03-31 20:28:49
    python进程通信之内存共享
    """
    内存共享:
        在内存中开辟一块空间,进程可以写入和读取内容完成通信,但是每次写入会覆盖之前的内容
        只能保存一次的写入内容
    实现步骤:
        1.Value的实现方法
            1.开辟内存空间        v=Value(ctype,data)
                    ctype:表示共享内存空间的类型  'i'表示int  'f'表示float  'c'表示字节串
                    data: 表示初始化数据
            2.对属性的查看和修改就是队内存的读写    v.value
        2.Array的实现方法
            1.开辟内存空间        a=Array(ctype,data)
                    ctype: 表示共享内存数据类型
                    data: 整数表示开辟空间大小
            2.读取和写入   通过遍历获取每个值,也可以通过索引
    """
    from multiprocessing import Process, Value, Array
    
    # 开辟内存空间,定义数据类型和初始值
    val = Value("f", 200)
    arr = Array("i", [1,5,6,8])
    
    
    def fun1():
        val.value = 3.1415926
        num = 1
        for i in range(8):
            print(arr[i])
            arr[i] = 8
            num += 1
    
    
    if __name__ == "__main__":
        # 创建进程对象并绑定函数
        p = Process(target=fun1)
        # 开启进程
        p.start()
        # 回收进程
        p.join()
        print(val.value)
        print(arr[:])
    
    
    展开全文
  • ROS系统节点间的内存共享

    千次阅读 2020-01-30 15:08:37
    ROS系统节点间的内存共享 为什么要用内存共享? 答案是ROS提供的服务或者话题都是通过网络来实现的。这样做虽然更具普遍性,照顾到ROS节点可能架设在不同的硬件上这一点,然对于在同一台设备的两个节点间传输数据...

    为什么要用内存共享?

    答案是ROS提供的服务或者话题都是通过网络来实现的。照顾到ROS节点可能架设在不同的硬件上这一点,这样做更具普遍性,但对于在同一台设备的两个节点间传输数据是非常不友好的。因为其既没必要性又浪费大量资源,且效率低下,容易造成网络堵塞,延时严重。

    那么怎么改善最好呢,自然是进程间的内存共享。我们直接让两个节点共享一片物理内存,在里面做一个队列数据结构,一个往里面写,一个去里面读。

    下面我们就来实现这一功能。跟上篇文章一样,我们先实现纯净的Linux C++版本,然后再把代码移植到ROS的节点中。

    在C++中怎么共享内存?

    实现Linux进程间的内存共享,主要参考这篇文章

    写进程

    “写”进程,流程如下:

    1. 获得key, ftok()

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

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

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

    5. 解除映射 shmdt()

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

    代码如下:

    #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 = (int *)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;
    }

    读进程

    “读”进程,流程如下:

    1. 获得key, ftok()

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

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

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

    5. 解除映射 shmdt()

    代码如下:

    #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;
    }

    将上述代码移植进ROS

    创建writeshmInRos.cpp

    #include <ros/ros.h>
    #include <iostream>
    #include "lcm/lcm-cpp.hpp"
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h> 
    int main(int argc, char** argv)
    {
      ros::init(argc, argv, "image_publisher");  
      ros::NodeHandle nh;   
      // 生成一个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 = (int *)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);  
      }   
      ros::spinOnce();}

    创建readshmInRos.cpp

    #include <ros/ros.h>
    #include <iostream>
    #include "lcm/lcm-cpp.hpp"
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h> 
    int main(int argc, char** argv)
    {
      ros::init(argc, argv, "image_publisher");  
      ros::NodeHandle nh;   
      // 生成一个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);  
      }   ros::spinOnce();
    }

    运行结果如下:
    在这里插入图片描述
    本文转载自:https://blog.csdn.net/weixinhum/article/details/84585954

    展开全文
  • python 多进程之间内存共享

    千次阅读 2019-09-14 10:33:30
    进程是一个独立的资源管理单元,不同进程间的资源是独立的,不能在一个进程中访问另一个进程的用户空间和内存空间。但是,进程不是孤立的,不同进程之间需要信息的交互和状态的传递,因此需要进程间数据的传递、同步...

    进程:
    进程是一个独立的资源管理单元,不同进程间的资源是独立的,不能在一个进程中访问另一个进程的用户空间和内存空间。但是,进程不是孤立的,不同进程之间需要信息的交互和状态的传递,因此需要进程间数据的传递、同步和异步的机制。

    当然,这些机制不能由哪一个进程进行直接管理,只能由操作系统来完成其管理和维护,Linux提供了大量的进程间通信机制,包括同一个主机下的不同进程和网络主机间的进程通信

    同一主机间的信息交互:

    • 无名管道
      特点:多用于亲缘关系进程间通信,方向为单向;为阻塞读写;通信进程双方退出后自动消失
      问题:多进程用同一管道通信容易造成交叉读写问题
    • 有名管道
      FIFO,方向为单向(双向需要两个FIFO),以磁盘文件的方式存在;通信双方一方不存在则阻塞
    • 消息队列
      可用于同一主机任意多进程的通信,但其可存放的数据有限,应用于少量的数据传递
    • 共享内存
      可实现通一主机任意进程间大量数据的通信,但多进程对共享内存的访问存在着竞争
    • 文件
      文件是进程安全的

    同一主机进程间的同步机制:信号量
    同一主机进程间的异步机制:信号

    多进程共享内存:
    最简单的就是文件,文件时进程安全的
    若数据量不时很大,可以用python自带的Queue,Pipe等
    若数尽量很大的话,使用中间媒介,如:数据库,redis

    网络主机间数据交互:

    • Socket套接字

    1. 共享内存的概念:
    共享内存,主要是实现进程间大量数据的传输。所谓共享内存,即在内存中开辟一段特殊的内存空间,多个进程可互斥访问,该内存空间具有自身特有的数据结构。

    • 多个进程在使用此共享内存空间时候,必须在进程地址空间与共享内存地址空间之间建立连接,即将共享内存空间挂载到进程中;
    • 共享内存是由一个进程开辟,其它任何进程都可以挂载;
    • 共享内存并不会随着进程的退出而消失,因此最后不使用此内存空间时,必须要手动删除。

    2. python中共享内存模块:
    python的multiprocessing模块也给我们提供了共享内存的操作

    一般的变量在进程之间是没法进行通讯的,multiprocessing 给我们提供了 ValueArray 模块,他们可以在不通的进程中共同使用

    假如用Process了几个子进程:

    1. 子进程继承父进程的全局变量,而且是以复制的形式完成(进程数大容易内存溢出),所以子进程修改后的全局变量只对自己和自己的子进程有影响。
    2. 父子进程不共享这些全局变量,也就是说:父进程中对全局变量的修改不影响子进程中的全局变量,同理,子进程也不影响父进程的。

    为了实现父子进程的通信:value和array方法

    1. Value函数返回一个 shared memory 包装类,其中包含一个 ctypes 对象,一般 整数用 i ,字符用 c ,浮点数用 d 就可以了
    2. Array函数返回一个 shared memory 包装类,其中包含一个数组,字符串需要用 Array 来传递。
      创建一个 lock 来控制对 value 的访问,该参数可以是 Lock 也可以是 RLock 对象。
    展开全文
  • c# 内存共享操作,可以创建、读取、写入内存共享区,
  • Android系统共享内存

    千次阅读 2020-11-18 10:42:58
    1.共享内存简介 共享内存是进程间通讯的一种方式,通过映射一块公共内存到各自的进程空间来达到共享内存的目的。 通常进程内存空间是4G,这个大小是由内存指针长度决定的,如果指针长度32位,那么地址最大编号为0...
  • 想必在Linux上写过程序的同学都有分析进程占用多少内存的经历,或者被问到这样的问题,你的程序在运行时占用了多少内存(物理内存)? 通常我们可以通过top命令查看进程占用了多少内存。这里我们可以看到VIRT、RES...
  • qt共享内存

    千次阅读 2021-07-02 15:36:35
    查看此文,共享内存,相信大家都知道进程间通信,即IPC(Inter-Process Communication),进程间通信是指两个进程的数据之间产生交互。而共享内存是实现进程通信的方式之一,其他通信方式可看下图: 查看各通信方式...
  • 内存共享(Shared Memory)

    千次阅读 2015-06-22 06:22:11
    一、什么是内存共享 内存共享时一种常用的进程间通信的机制。说白了,就是让进程直接去访问同一块内存区域。 优点:都直接访问内存了,那必然速度是很快的。 缺点:没有制定多进程同步的问题,要解决这问题,还需要...
  • 继续以“以通信方式共享内存,不要以共享内存方式通信”这句话展开。 从云原生开始。 云原生是面向微服务的架构,而消息传递是微服务交互的媒介,每个工人都接触过关于消息队列的概念,正是消息支撑了云原生微服务。 ...
  • 本文介绍共享内存的概念及使用。进程间通信(IPC,InterProcess Communication) 是指在不同进程之间传播或交换信息,现在linux使用的进程间通信方式有:(1)管道(pipe)和命名管道(FIFO) (2)信号(signal) ...
  • Linux共享内存

    千次阅读 2022-02-04 22:56:58
    文章目录一、使用流程使用步骤1.ftok函数生成键值2.shmget函数创建共享存储空间并返回一个共享存储标识符3.shmat函数获取第一个可用共享内存空间的地址4.shmdt函数进行分离5.shmctl函数对共享内存进行控制编程验证...
  • Linux进程间的循环队列内存共享

    千次阅读 2018-12-17 21:26:12
    上一篇文章我们已经介绍了进程间的内存共享。因为篇幅关系,只是做了简单实现,并不适用于实际应用。因此本篇以实际应用为目的,介绍以循环队列实现的内存共享机制。 该机制可以快速实现数据的先入先出,方便控制...
  • 标准C++类std::string的内存共享和Copy-On-Write(写时拷贝),引用计数实现
  • 【需求描述】 1、共享内存保存信息 2、提供接口写入共享内存 3、提供接口获取共享内存 【编写语言:C】 【环境:linux】 1、写入内存一千万条数据 耗时:5.356秒 2、读取内存一千万条数据 耗时:1.449秒
  • Linux之共享内存

    千次阅读 2022-02-24 09:46:56
    Linux之共享内存
  • 一、简介 共享内存允许两个进程访问同一块内存区域,它们使用同一个 key 值标记。 二、特点 优点: 通信方便,两个进程也是直接访问同一块内存区域,减少了数据复制的操作,速度上...2. 创建内存共享区 int sh...
  • linux 下的内存共享

    千次阅读 2013-09-27 14:37:56
    共享内存是最快的进程间...实际上,进程之间在共享内存时,并不总是读写少量数据后就解除映射,有新的通信时,再重新建立共享内存区域,而是保持共享区域,直到通信完毕为止,这样,数据内容一直保存在共享内存中,并没
  • 对线程间共享内存的问题,许多同学是不是都觉得很简单?就是用全局变量来共享码,然而你说的并没有什么卵用…….(^__^)……. 对于线程间内存关系不弄得清清楚楚,很难写好多线程程序。最简练而精准的话来形容线程间...
  • linux进程间通信———内存共享

    千次阅读 2017-03-16 19:08:23
    共享内存(shared memory):是linux下的多进程之间的通信方法,这种方法通常用于一个程序的多进程间通信,实际上多个程序间也可以通过共享内存来传递信息。共享内存指在多处理器的计算机系统中,可以被不同中央处理...
  • C语言共享内存-基本操作

    千次阅读 2021-05-21 07:38:31
    } printf("创建共享内存成功,shmid=%d\n",shmid); if((pstr=shmat(shmid,NULL,0))==(void *)(-1)) { perror("shmat error"); exit(1); } printf("连接共享内存成功,地址是%p\n",pstr); w_shm(pstr); display_shm...
  • Qt 读写共享内存

    千次阅读 2020-10-01 14:05:43
    Qt 读写共享内存 一、简述 记--使用Qt进行简单的读写共享内存。 二、工程结构 三、测试代码 #include <QDebug> #include <QSharedMemory> //测试使用的数据结构 typedef struct{ int age; ...
  • linux实现共享内存同步的四种方法

    千次阅读 2021-05-11 12:29:01
    共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝。它是IPC对象的一种。为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将其映射到自己的私有...
  • 一、引言 之前的管道学习中,我们利用命名管道生成了两个.fifo的文件,如果用户不懂技术,以为这个文件没用就可能把它们删除了。...共享内存是由IPC为一个进程创建的一个特殊的地址范围,它将出现在进程的
  • 文章目录共享内存与UDP通信比较MATLAB共享内存Simulink共享内存C#共享内存(C或者C++类似) 共享内存与UDP通信比较 MATLAB/Simulink将计算或者仿真数值传递给其他应用软件或者其他硬件平台最简单的方法是采用UDP通信...
  • 多台计算机共享内存 共享内存多处理器 (Shared Memory Multiprocessor) There are three types of shared memory multiprocessor: 共有三种类型的共享内存多处理器: UMA (Uniform Memory Access) UMA(统一内存...
  • k8s笔记15--配置共享内存

    千次阅读 2022-04-23 17:39:22
    k8s笔记15--配置共享内存 介绍 案例 docker 环境 说明 介绍 容器启动后默认会有 64M 的共享内存挂载在/dev/shm 目录,用户可以向访问本地文件系统一样访问该共享内存,如果需要配置更大的内存,那么在docker中需要...
  • 引言 python使用共享内存进行通信
  • 共享内存原理及实现通信过程

    千次阅读 2022-02-14 09:25:04
    共享内存原理及实现通信过程共享内存的概念及创建过程共享内存的使用函数使用共享内存完成通信 共享内存的概念及创建过程 一. 共享内存的概念 共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,096,024
精华内容 438,409
关键字:

内存共享