【问题标题】:Shared memory deleted at exit退出时删除共享内存
【发布时间】:2020-09-28 12:47:57
【问题描述】:

我有两个脚本,一个用于创建和写入共享内存块,另一个用于读取该共享内存。 问题是当第一个脚本结束时,即使我没有取消链接,共享内存也会被删除。 这是我的第一个脚本:

import argparse
import csv
import os
import subprocess
import sys
import time

from classes.rtData import RtData
from multiprocessing import shared_memory

if '__main__' == __name__:
    sys.stdout.write('starting server ... \n')
    service = RtData()

    shm_a = shared_memory.SharedMemory(name='rtdata', create=True, size=len(msg))
    data = shm_a.buf
    data[0] = 42
    shm_a.close

添加断点时,我可以看到共享内存已创建:

$ ls -l /dev/shm/

共 0 -rw------- 1 facundo facundo 4 Sep 28 09:41 rtdata

但是当脚本退出时,共享内存被删除(所以我不能用第二个脚本读取它)

【问题讨论】:

  • 共享内存块将持续存在,只要任何进程打开它。终止创建进程不会自动删除共享内存。
  • 这就是我的问题。也许顺序应该是: a) 进程 I 创建共享内存,但不关闭它。 b) 进程 II 打开相同的共享内存并使用它。但这不是我需要的。这个想法是一个进程有责任保持共享内存更新(但在这样做之后完成执行)......然后应该触发的任何其他进程访问共享内存以使用它。
  • 如果我正确理解您的情况,听起来常规文件将是更合适的解决方案。共享内存(和类似概念)实际上是用于在同时运行的进程之间共享数据。
  • 我正在寻找的是处理许多不同时运行的进程共享的内存区域(将根据请求运行)。它是针对 scada 系统中的数据采集。让我困惑的是文档中的文本“只要打开任何进程,共享内存块就会一直存在。终止创建进程不会自动删除共享内存”(调用 .unlink 方法)

标签: shared-memory python-3.8


【解决方案1】:

我找到了原因。 The documentation states that

当一个进程不再需要访问其他进程可能仍需要的共享内存块时,应该调用close() 方法

我发现了与此问题相关的错误报告https://bugs.python.org/issue39959#msg368770

我通过在消费过程中添加unregister( shared_memory_name, 'shared_memory')在我的过程中对其进行了测试,它工作正常。

【讨论】:

  • “否则,unlink() 会自动执行”——你在哪里看到的?它充其量是暗示的,而且,我认为,甚至不是这样。此外,based on the code 似乎并非如此。 __del__ 调用 close,但不调用 unlink
  • 你是对的。我在代码上没有看到。我会做进一步的测试。谢谢。
【解决方案2】:

您似乎缺少管理器进程

例如(https://www.geeksforgeeks.org/multiprocessing-python-set-2/): 导入多处理

def print_records(records): 
    """ 
    function to print record(tuples) in records(list) 
    """
    for record in records: 
        print("Name: {0}\nScore: {1}\n".format(record[0], record[1])) 

def insert_record(record, records): 
    """ 
    function to add a new record to records(list) 
    """
    records.append(record) 
    print("New record added!\n") 

if __name__ == '__main__': 
    with multiprocessing.Manager() as manager: 
        # creating a list in server process memory 
        records = manager.list([('Sam', 10), ('Adam', 9), ('Kevin',9)]) 
        # new record to be inserted in records 
        new_record = ('Jeff', 8) 

        # creating new processes 
        p1 = multiprocessing.Process(target=insert_record, args=(new_record, records)) 
        p2 = multiprocessing.Process(target=print_records, args=(records,)) 

        # running process p1 to insert new record 
        p1.start() 
        p1.join() 

        # running process p2 to print records 
        p2.start() 
        p2.join() 

【讨论】:

  • 这似乎与 OP 的问题正交——管理器不需要使用共享内存。
猜你喜欢
  • 2012-11-02
  • 2013-05-21
  • 2021-09-19
  • 2018-10-03
  • 2013-03-14
  • 1970-01-01
  • 1970-01-01
  • 2013-10-04
  • 2018-10-21
相关资源
最近更新 更多