子进程可以创建共享内存并与父进程共享吗?

问题描述 投票:0回答:1

子进程可以创建SharedMemory对象并与父进程共享吗?目前,我在尝试时遇到错误。我需要这个,因为创建和复制内存是我的应用程序中的主要性能瓶颈,但我需要在父进程中写入共享内存。

以下是说明该问题的三个最小示例。我使用 time.sleep(1) 来控制父进程或子进程是否先完成。

情况1(无错误):在父进程中创建共享内存,与子进程共享

import time
from multiprocessing import shared_memory, Process
def worker():
    shm = shared_memory.SharedMemory(name="test")

shm = shared_memory.SharedMemory(name="test", create=True, size=1)
Process(target=worker).start()
time.sleep(1)
shm.unlink()

情况 2(无错误):在子进程中创建共享内存,而不与父进程共享

import time
from multiprocessing import shared_memory, Process
def worker():
    shm = shared_memory.SharedMemory(name="test", create=True, size=1)
    time.sleep(1)
    shm.unlink()

Process(target=worker).start()

情况3(错误):在子进程中创建共享内存,与父进程共享

import time
from multiprocessing import shared_memory, Process
def worker():
    shm = shared_memory.SharedMemory(name="test", create=True, size=1)
    time.sleep(1)
    shm.unlink()


Process(target=worker).start()
shm = shared_memory.SharedMemory(name="test")

追溯:

Traceback (most recent call last):
  File "/home/benjamin/Documents/duckit/covin.py", line 24, in <module>
    shm = shared_memory.SharedMemory(name="test")
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/benjamin/miniforge3/envs/hichdev/lib/python3.12/multiprocessing/shared_memory.py", line 104, in __init__
    self._fd = _posixshmem.shm_open(
               ^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '/test'

动机:

我尝试在一堆文件上的多个子进程中使用 numpy loadtxt (CPU 瓶颈任务,而不是 I/O 瓶颈任务,因此是通过多处理完成的)。然后我想将数组写入 HDF5 文件,在主线程中按顺序完成时效率最高。如果必须复制数组才能让父进程接收它们(例如通过多处理队列传递或返回它们时),那么这将成为整个程序的性能瓶颈。因此,我想将数组复制到子进程中的共享内存中,并与父进程共享它们以便写入它们。

python multiprocessing shared-memory
1个回答
0
投票

如果父进程首先尝试连接到内存,则非工作情况会出现竞争条件。 您可以使用事件让父/子了解共享内存的状态:

import multiprocessing as mp
import multiprocessing.shared_memory as sm

def worker(ready, done):
    shm = sm.SharedMemory(name="test", create=True, size=1)
    shm.buf[0] = 123
    ready.set()  # Let parent know shared memory is set up
    done.wait()  # Wait for parent to finish with shared memory
    shm.unlink()

if __name__ == '__main__':  # Idiom to work with both Linux and Windows
    ready = mp.Event()
    done = mp.Event()
    mp.Process(target=worker, args=(ready, done), daemon=True).start()
    ready.wait()  # Wait for child to set up shared memory
    shm = sm.SharedMemory(name="test")
    print(shm.buf[0])
    done.set()  # Let child know parent is finished with shared memory

输出:

123
© www.soinside.com 2019 - 2024. All rights reserved.