如何分配共享内存,以便父进程可以看到子进程中的写操作?

时间:2019-07-11 15:36:12

标签: python multiprocessing shared-memory

背景:我正在编写一个程序,可以同时读取多个摄像机的视频帧。我想有1个执行帧读取的进程和2个将那些帧写入磁盘的进程。我一直在尝试寻找最佳方法(在Python 3.6中),以使“读取”过程中的帧可用于“写入”过程进行保存。我已经将共享内存作为最佳选择。

问题::当我为两个进程分配共享内存时,子进程看不到父进程在共享内存空间中所做的更改。

先前的工作:我一直在尝试Is shared readonly data copied to different processes for multiprocessing?建议的方法。但是,直接将此代码粘贴到Atom中并尝试在Python 2.7或Python 3.6下运行它不会产生链接的答案所提供的结果(即,父进程在子进程中看不到my_func所做的更改)过程)

注意:

import multiprocessing
import ctypes
import numpy as np

shared_array_base = multiprocessing.Array(ctypes.c_double, 10*10)
shared_array = np.ctypeslib.as_array(shared_array_base.get_obj())
shared_array = shared_array.reshape(10, 10)

# Parallel processing
def my_func(i, def_param=shared_array):
    shared_array[i,:] = i

if __name__ == '__main__':
    pool = multiprocessing.Pool(processes=4)
    pool.map(my_func, range(10))

    print shared_array

1 个答案:

答案 0 :(得分:0)

正在玩一些应该与Unix和Windows兼容的东西。我想到的第一个想法是使用内存映射文件,因为这基本上是共享内存的机制

在Python下使用它们非常容易。例如,这是一个以这种方式创建numpy数组的函数:

import numpy as np
from ctypes import sizeof, c_double
from mmap import mmap, ACCESS_DEFAULT

def shared_array(
    shape, path, mode='rb', *,
    dtype=c_double, access=ACCESS_DEFAULT
):
    for n in reversed(shape):
        dtype *= n
    with open(path, mode) as fd:
        if fd.writable():
            size = fd.seek(0, 2)
            if size < sizeof(dtype):
                fd.truncate(sizeof(dtype))
        buf = mmap(fd.fileno(), sizeof(dtype), access=access)
    return np.ctypeslib.as_array(
        dtype.from_buffer(buf)
    )

即创建具有给定形状(即(len,)(rows, cols))的“共享numpy数组”,该形状出现在文件系统中给定路径上,并由mode(即{{ 1}}为只读,rb为读写)。

这可以与以下代码一起使用:

r+b

我使用Linux,因此已显式设置Windows样式过程from multiprocessing import Pool, set_start_method def fn(shape, path): array = shared_array(shape, path, 'r+b') np.fill_diagonal(array, 42) def main(): shape = (5, 10) path = 'tmp.buffer' array = shared_array(shape, path, 'w+b') with Pool() as pool: pool.apply(fn, (shape, path)) print(array) if __name__ == '__main__': set_start_method('spawn') main() 的样式

相关问题