Linux 上共享内存的 FileNotFoundError

Mat*_*ias 6 python linux shared-memory multiprocessing python-multiprocessing

我正在尝试为我的 Python 应用程序创建一个共享内存,该内存应该在父进程以及从该父进程生成的另一个进程中使用。在大多数情况下,工作正常,但是,有时我会得到以下堆栈跟踪:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python3.8/multiprocessing/spawn.py", line 116, in spawn_main
    exitcode = _main(fd, parent_sentinel)
  File "/usr/lib/python3.8/multiprocessing/spawn.py", line 126, in _main
    self = reduction.pickle.load(from_parent)
  File "/usr/lib/python3.8/multiprocessing/synchronize.py", line 110, in __setstate__
    self._semlock = _multiprocessing.SemLock._rebuild(*state)
FileNotFoundError: [Errno 2] No such file or directory: '/psm_47f7f5d7'
Run Code Online (Sandbox Code Playgroud)

我想强调的是,我们的代码/应用程序在 99% 的情况下都可以正常工作。我们在应用程序中定期为每个此类进程生成新的共享内存(这是一个服务器进程,因此它每天 24/7 运行)。几乎所有时候这都工作正常,只是偶尔会抛出上面的错误,然后杀死整个应用程序。

更新:我注意到这个问题主要发生在应用程序已经运行了一段时间的时候。当我启动它时,共享内存的创建和生成新进程工作正常,没有此错误。

共享内存是这样创建的:

# Spawn context for multiprocessing
_mp_spawn_ctxt = multiprocessing.get_context("spawn")
_mp_spawn_ctxt_pipe = _mp_spawn_ctxt.Pipe

# Create shared memory
mem_size = width * height * bpp
shared_mem = shared_memory.SharedMemory(create=True, size=mem_size)
image = np.ndarray((height, width, bpp), dtype=np.uint8, buffer=shared_mem.buf)
parent_pipe, child_pipe = _mp_spawn_ctxt_pipe()
time.sleep(0.1)

# Spawn new process
# _CameraProcess is a custom class derived from _mp_spawn_ctxt.Process
proc = _CameraProcess(shared_mem, child_pipe)
proc.start()
Run Code Online (Sandbox Code Playgroud)

有什么想法可能是这里的问题吗?

JIS*_*IST 0

我遇到了类似的问题,以防更多进程可以访问共享内存/对象,并且一个进程确实更新了共享内存/对象。

我根据以下步骤解决了这些问题:

  • 我通过互斥体同步了与共享内存/对象的所有操作(请参阅多处理使用superfastpython保护共享资源的示例)。代码的关键部分是创建、更新、删除,而且还要读取共享对象/内存的内容,因为同时不同的进程可以更新共享对象/内存等。
  • 我避免使用仅支持单线程执行的库

请参阅同步示例代码:

def increase(sharedObj, lock):
    for i in range(100):
        time.sleep(0.01)
        lock.acquire()
        sharedObj = sharedObj + 1
        lock.release()

def decrease(sharedObj, lock):
    for i in range(100):
        time.sleep(0.001)
        lock.acquire()
        sharedObj = sharedObj - 1
        lock.release()

if __name__ == '__main__':
    sharedObj = multiprocessing.Value ('i',1000)
    lock=multiprocessing.Lock()
    p1=multiprocessing.Process(target=increase, args=(sharedObj, lock))
    p2=multiprocessing.Process(target=decrease, args=(sharedObj, lock))
    p1.start()
    p2.start()
    p1.join()
    p2.join()
Run Code Online (Sandbox Code Playgroud)