gpt4 book ai didi

python - 当我调用 multiprocessing.Process 时,正在 pickle 什么?

转载 作者:太空宇宙 更新时间:2023-11-03 12:47:49 26 4
gpt4 key购买 nike

我知道 multiprocessing 使用 pickle 以使进程在不同的 CPU 上运行,但我想我对 pickle 的内容有点困惑。让我们看看这段代码。

from multiprocessing import Process

def f(I):
print('hello world!',I)

if __name__ == '__main__':
for I in (range1, 3):
Process(target=f,args=(I,)).start()

我假设被 pickle 的是 def f(I) 和进入的参数。首先,这个假设是否正确?

其次,假设 f(I) 中有一个函数调用,例如:

def f(I):
print('hello world!',I)
randomfunction()

randomfunction 的定义是否也被 pickle 了,还是只是函数调用?

此外,如果该函数调用位于另一个文件中,进程是否能够调用它?

最佳答案

在此特定示例中,pickle 的内容取决于平台。在支持 os.fork 的系统上,比如 Linux,这里没有 pickle。目标函数和您传递的参数都通过 fork 被子进程继承。

在不支持 fork 的平台上,例如 Windows,f 函数和 args 元组都将被 pickle 并发送到子进程。子进程将重新导入您的 __main__ 模块,然后解开该函数及其参数。

无论哪种情况,randomfunction 实际上都没有被 pickle。当您 pickle f 时,您真正 pickle 的只是一个指针,供子函数重新构建 f 函数对象。这通常只是一个字符串,告诉 child 如何重新导入 f:

>>> def f(I):
... print('hello world!',I)
... randomfunction()
...
>>> pickle.dumps(f)
'c__main__\nf\np0\n.'

子进程将重新导入f,然后调用它。 randomfunction 只要正确导入到原始脚本中就可以访问。

请注意,在 Python 3.4+ 中,您可以使用 contexts 在 Linux 上获得 Windows 风格的行为。 :

ctx = multiprocessing.get_context('spawn')
ctx.Process(target=f,args=(I,)).start() # even on Linux, this will use pickle

上下文的描述也可能与此相关,因为它们也适用于 Python 2.x:

spawn

The parent process starts a fresh python interpreter process. The child process will only inherit those resources necessary to run the process objects run() method. In particular, unnecessary file descriptors and handles from the parent process will not be inherited. Starting a process using this method is rather slow compared to using fork or forkserver.

Available on Unix and Windows. The default on Windows.

fork

The parent process uses os.fork() to fork the Python interpreter. The child process, when it begins, is effectively identical to the parent process. All resources of the parent are inherited by the child process. Note that safely forking a multithreaded process is problematic.

Available on Unix only. The default on Unix.

forkserver

When the program starts and selects the forkserver start method, a server process is started. From then on, whenever a new process is needed, the parent process connects to the server and requests that it fork a new process. The fork server process is single threaded so it is safe for it to use os.fork(). No unnecessary resources are inherited.

Available on Unix platforms which support passing file descriptors over Unix pipes.

请注意,forkserver 仅在 Python 3.4 中可用,无论您使用何种平台,都无法在 2.x 上获得该行为。

关于python - 当我调用 multiprocessing.Process 时,正在 pickle 什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26025878/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com