Python `ShareableList` 在“阅读”进程关闭时被删除

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

我在Python中有一个“主”进程(只写),它生成一个ID列表,我想与同一台机器上的其他独立创建Python进程(只读)共享该列表。我希望无论是否有任何“读取”进程退出,该列表都会持续存在。我一直在探索

ShareableList
SharedMemory
中的
multiprocessing
,看看它是否适合这个用例,但遇到了一些我没有预料到的行为。以下是我为测试这一点而编写的脚本。

shareable_list.py

import argparse
from multiprocessing import shared_memory


def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("--name", type=str, default="shared-memory-test",
                        help="name of shared memory block")
    parser.add_argument("--process-type", type=str, default="read", help="If 'write', then "
                        "write to shared memory. If 'read', then read from shared memory.")
    return parser.parse_args()


if __name__ == "__main__":
    args = parse_args()
    max_seq_len = 64

    if args.process_type == "write":
        # initialize shared memory (preallocate in case I need to add more)
        share = shared_memory.ShareableList(sequence=["" for _ in range(max_seq_len)],
                                            name=args.name)
        print(f"created shared memory block {args.name} with sequence length {max_seq_len}")
        for i, data in enumerate(["a", "b", "c", "d", "e"]):
            data = str(i)
            print(f"writing {data} to shared memory")
            share[i] = data
    elif args.process_type == "read":
        # read data from shared_memory
        share = shared_memory.ShareableList(name=args.name)
        for i, data in enumerate(share):
            if data:
                print(f"read {data} from shared memory index {i}")
    else:
        raise ValueError(f"invalid process_type: {args.process_type}")

    # stall until user quits
    input("Press enter to quit:")

    # close shared memory
    share.shm.close()
    if args.process_type == "write":
        share.shm.unlink()
        print(f"unlinked shared memory")

这是我测试的方法:

  1. 运行
    python shareable_list.py --process-type write
    创建并填充
    ShareableList
    对象。让这个过程继续下去。
  2. 打开一个新的 shell 并运行
    python shareable_list.py --process-type read
  3. 打开第三个 shell 并运行
    python shareable_list.py --process-type read

第一个进程输出以下内容(这是预期的):

created shared memory block shared-memory-test with sequence length 64
writing 0 to shared memory
writing 1 to shared memory
writing 2 to shared memory
writing 3 to shared memory
writing 4 to shared memory

第二个和第三个进程输出这个(也是预期的):

read 0 from shared memory index 0
read 1 from shared memory index 1
read 2 from shared memory index 2
read 3 from shared memory index 3
read 4 from shared memory index 4

但是,当我按“Enter”关闭第二个或第三个进程时,我收到以下警告:

UserWarning: resource_tracker: There appear to be 1 leaked shared_memory objects to clean up at shutdown

它似乎还删除了共享内存块。关闭“读取”进程后,打开任何新的“读取”进程或关闭“写入”进程会导致以下错误:

FileNotFoundError: [Errno 2] No such file or directory: '/shared-memory-test'

阅读完关于

close()
unlink()
的文档后,我假设我想在“读”进程结束之前调用
close()
,并在“写”进程之前调用
close()
unlink()
过程结束。我最好的猜测是,这里的“读取”进程认为它们是唯一跟踪该对象的进程,并因此将其关闭。我这里的理解不正确吗?这是否是解决我的问题的好方法?谢谢。

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

这似乎是 Python 库中的一个错误。

看这个答案

该错误已报告在这里

看起来它将在计划于 2024 年 10 月发布的 Python 3.13 中得到修复(或解决),并且在“读取”过程中需要一个额外的参数

track=True

虽然很容易重现这个问题,但我也发现它并不总是发生。

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