【发布时间】:2022-01-02 00:08:20
【问题描述】:
我了解有多种技术可以在 python 中的进程之间共享内存和数据结构。这个问题专门针对存在于 python 3.6 中但似乎不再存在于 3.10 中的 python 脚本中的这种固有共享内存。 有谁知道为什么以及是否有可能在 3.10 中恢复此功能?或者我观察到的这种变化是什么?我已经将我的 Mac 升级到 Monterey,它不再支持 python 3.6,所以我不得不升级到 3.9 或 3.10+。
注意:我倾向于在 Mac 上开发并在 Ubuntu 上运行生产。不知道这是否是这里的因素。从历史上看,在 3.6 中,无论操作系统如何,一切都表现相同。
使用以下 python 文件制作一个简单的项目
myLibrary.py
MyDict = {}
test.py
import threading
import time
import multiprocessing
import myLibrary
def InitMyDict():
myLibrary.MyDict = {'woot': 1, 'sauce': 2}
print('initialized myLibrary.MyDict to ', myLibrary.MyDict)
def MainLoop():
numOfSubProcessesToStart = 3
for i in range(numOfSubProcessesToStart):
t = threading.Thread(
target=CoolFeature(),
args=())
t.start()
while True:
time.sleep(1)
def CoolFeature():
MyProcess = multiprocessing.Process(
target=SubProcessFunction,
args=())
MyProcess.start()
def SubProcessFunction():
print('SubProcessFunction: ', myLibrary.MyDict)
if __name__ == '__main__':
InitMyDict()
MainLoop()
当我在 3.6 上运行它时,它的行为与 3.10 明显不同。我确实理解子进程不能修改主进程的内存,但是访问之前设置的主进程的数据结构仍然非常方便,而不是将每一个小东西都移动到共享内存中只是为了读取一个简单的字典/int/字符串/等。
Python 3.10 输出:
python3.10 test.py
initialized myLibrary.MyDict to {'woot': 1, 'sauce': 2}
SubProcessFunction: {}
SubProcessFunction: {}
SubProcessFunction: {}
Python 3.6 输出:
python3.6 test.py
initialized myLibrary.MyDict to {'woot': 1, 'sauce': 2}
SubProcessFunction: {'woot': 1, 'sauce': 2}
SubProcessFunction: {'woot': 1, 'sauce': 2}
SubProcessFunction: {'woot': 1, 'sauce': 2}
观察:
请注意,在 3.6 中,子进程可以查看从主进程设置的值。但是在 3.10 中,子进程看到的是一个空字典。
【问题讨论】:
-
target=CoolFeature()没有意义。为什么这个测试用例首先需要线程? -
@o11c 你可以忽略线程。这种行为在没有线程的情况下仍然存在。测试用例根本不需要线程。我试图重现该错误,并试图与我的代码所做的非常相似。
-
我对@987654327@ 不是特别熟悉,但您是否有可能使用基于
spawn的池而不是基于fork的池? -
这不是“固有共享内存”。
multiprocessing从未提供过这样的功能。你在 Mac 上吗? Mac 上 3.8 中的默认启动方法发生了变化,这可以解释观察到的差异。 -
@o11c 这可能是正确的。请参阅下面的链接。 “在 3.8 版中更改:在 macOS 上,spawn start 方法现在是默认的。fork start 方法应该被认为是不安全的,因为它可能导致子进程崩溃”。但我想知道这对 Ubuntu vs mac 意味着什么……因为我两者都用。 docs.python.org/3/library/…
标签: python python-3.x multiprocessing shared-memory