当前位置: 首页 > 面试题库 >

如何在python子进程之间传递大型numpy数组而不保存到磁盘?

凌和悦
2023-03-14
问题内容

有没有一种好方法可以在不使用磁盘的情况下在两个python子进程之间传递大量数据?这是我希望完成的动画片示例:

import sys, subprocess, numpy

cmdString = """
import sys, numpy

done = False
while not done:
    cmd = raw_input()
    if cmd == 'done':
        done = True
    elif cmd == 'data':
        ##Fake data. In real life, get data from hardware.
        data = numpy.zeros(1000000, dtype=numpy.uint8)
        data.dump('data.pkl')
        sys.stdout.write('data.pkl' + '\\n')
        sys.stdout.flush()"""

proc = subprocess.Popen( #python vs. pythonw on Windows?
    [sys.executable, '-c %s'%cmdString],
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE)

for i in range(3):
    proc.stdin.write('data\n')
    print proc.stdout.readline().rstrip()
    a = numpy.load('data.pkl')
    print a.shape

proc.stdin.write('done\n')

这将创建一个子进程,该子进程生成一个numpy数组并将该数组保存到磁盘。然后,父进程从磁盘加载阵列。有用!

问题是,我们的硬件生成数据的速度比磁盘读写速度快10倍。有没有一种方法可以将数据从一个python进程传输到另一个纯粹的内存中,甚至可能不复制数据?我可以做类似参考传递的事情吗?

我第一次尝试纯粹在内存中传输数据非常糟糕:

import sys, subprocess, numpy

cmdString = """
import sys, numpy

done = False
while not done:
    cmd = raw_input()
    if cmd == 'done':
        done = True
    elif cmd == 'data':
        ##Fake data. In real life, get data from hardware.
        data = numpy.zeros(1000000, dtype=numpy.uint8)
        ##Note that this is NFG if there's a '10' in the array:
        sys.stdout.write(data.tostring() + '\\n')
        sys.stdout.flush()"""

proc = subprocess.Popen( #python vs. pythonw on Windows?
    [sys.executable, '-c %s'%cmdString],
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE)

for i in range(3):
    proc.stdin.write('data\n')
    a = numpy.fromstring(proc.stdout.readline().rstrip(), dtype=numpy.uint8)
    print a.shape

proc.stdin.write('done\n')

这非常慢(比保存到磁盘要慢得多),而且非常脆弱。一定有更好的方法!

只要数据获取过程不会阻止父应用程序,我就不会嫁给“子流程”模块。我短暂地尝试了“多处理”,但到目前为止没有成功。

背景:我们有一块硬件,可以在一系列ctypes缓冲区中生成高达〜2 GB /
s的数据。处理这些缓冲区的python代码正忙于处理大量信息。我想将此信息流与在“主”程序中同时运行的其他几个硬件进行协调,而子进程之间不会相互阻塞。我当前的方法是在保存到磁盘之前将数据在子进程中分解一些,但是最好将全部资金传递给“主”进程。


问题答案:

在四处搜寻有关Joe Kington发布的代码的更多信息时,我发现了numpy-
sharedmem
软件包。从这个numpy
/ multiprocessing教程
来看,它似乎具有相同的知识遗产(也许基本上是相同的作者?–我不确定)。

使用sharedmem模块,您可以创建一个共享内存的numpy数组(太棒了!),并将其与如下所示的多重处理一起使用:

import sharedmem as shm
import numpy as np
import multiprocessing as mp

def worker(q,arr):
    done = False
    while not done:
        cmd = q.get()
        if cmd == 'done':
            done = True
        elif cmd == 'data':
            ##Fake data. In real life, get data from hardware.
            rnd=np.random.randint(100)
            print('rnd={0}'.format(rnd))
            arr[:]=rnd
        q.task_done()

if __name__=='__main__':
    N=10
    arr=shm.zeros(N,dtype=np.uint8)
    q=mp.JoinableQueue()    
    proc = mp.Process(target=worker, args=[q,arr])
    proc.daemon=True
    proc.start()

    for i in range(3):
        q.put('data')
        # Wait for the computation to finish
        q.join()   
        print arr.shape
        print(arr)
    q.put('done')
    proc.join()

运行收益

rnd=53
(10,)
[53 53 53 53 53 53 53 53 53 53]
rnd=15
(10,)
[15 15 15 15 15 15 15 15 15 15]
rnd=87
(10,)
[87 87 87 87 87 87 87 87 87 87]


 类似资料:
  • 问题内容: 我有2个人的wav对话(客户和技术支持),我有3个独立的功能,可提取1个声音,缩短10秒钟并将其转换为嵌入。 下面的功能比上面的功能减少10秒的wav文件。 如何将其以wav或其他格式传递而不将其保存到某个目录?它将在rest api中使用,我不知道它将在哪里保存该wav,因此最好以某种方式传递它。 问题答案: 我想通了-下面的函数可以正常工作,而无需保存,缓冲等。它接收一个wav文件

  • 我有一个方法,在. txt或. docx文件的代码的不同部分接收来自的。我想创建一个新的对象,从以后读取内容的字节,而不保存该文件到磁盘。这有可能吗?或者有更好的方法从文件字节中获取内容?

  • 我正在学习通过教程在父组件和子组件之间传递数据。我仔细检查了我的代码,仍然没有找出错误。 我的index.js Home.js 按钮更改链接onClick事件正在调用changeLink函数,该函数将新链接传递给props。 错误:-

  • 生成图像 用scipy.misc.toImage将图像保存到磁盘 从磁盘打开保存的图像文件 使用请求模块发送包含image opened image file对象的http请求 这非常好,但是我想摆脱步骤2和3,所以我不需要先将对象保存到磁盘,然后再加载它。相反,我希望在一个与http服务器兼容的文件对象中转换我的numpy数组,并直接发送它。(就像从open()中得到的一样) 例如,我知道用PI

  • 问题内容: 我正在以这种方式制作包含3个子组件的组件: 主要组成部分包含英雄列表。标头组件包含两个按钮,用于将主组件上的视图切换到列表或网格视图。 我现在遇到的问题是将数据从标头组件传递到主组件。因此,当我单击网格按钮时,主要内容上的视图应更改为网格视图,与行视图相同。 如何在角度1.5的子组件之间传递数据? 问题答案: 成分法 我建议您与Angular 2组件方法保持一致,并使用输入 / 输出方

  • 我正在创建一个用户设置帐户使用故事板的5个步骤。每个步骤都有一个ViewController:1:)输入姓名、联系人等,2:)导入照片,3:)输入等4:)更多输入5:)确认页面,如果用户点击“确认”->获取所有输入并上传解析。 我在网上搜索时得到的唯一解决方案是创建一个函数“Prepare for Segue”并传递信息...但对我来说,这没有任何意义: 如果我有1000个viewcontroll