python - Python 中的多处理问题。 Windows 与 Linux

标签 python linux windows multiprocessing

import random
import os
from multiprocessing import Process

num = random.randint(0, 100)

def show_num():
    print("pid:{}, num is {}".format(os.getpid(), num))

if __name__ == '__main__':
    print("pid:{}, num is {}".format(os.getpid(), num))
    p = Process(target=show_num)
    p.start()
    p.join()
    print('Parent Process Stop')

以上代码展示了创建进程的基本用法。如果我在windows环境下运行这个脚本,变量num在父进程和子进程中是不同的。但是,脚本在 Linux 环境之间运行时,变量 num 是相同的。 我了解他们创建流程的机制不同。比如windows系统就没有fork方法。 但是,有人可以给我更详细的解释他们的区别吗? 非常感谢。

最佳答案

解释您帖子中描述的行为的差异正是您提到的:start method用于创建流程。在 Unix 风格的操作系统上,默认是 fork。在 Windows 上,唯一可用的选项是 spawn

fork
this Wiki page 的概述部分所述(顺序略有不同):

The fork operation creates a separate address space for the child. The child process has an exact copy of all the memory segments of the parent process.

The child process calls the exec system call to overlay itself with the other program: it ceases execution of its former program in favor of the other.

这意味着,当使用 fork 时,子进程的地址空间中已经有变量 num 并使用它。 random.randint(0, 100) 不会再次调用。

生成
正如多处理文档所描述的那样:

The parent process starts a fresh python interpreter process.

在这个新的解释器进程中,执行生成子进程的模块。过于简单化,这将执行 python.exe your_script.py 第二次。因此,通过将对 random.randint(0, 100) 的另一个调用的返回值分配给它,在子进程中创建了一个新变量 num。因此很可能 num 的内容在进程之间不同。
顺便说一句,这也是您绝对需要维护的原因当使用 spawn 作为启动方法时,使用 if __name__ == '__main__' 习惯用法的进程的实例化和启动,否则你最终会得到:

RuntimeError: 
        An attempt has been made to start a new process before the
        current process has finished its bootstrapping phase.

        This probably means that you are not using fork to start your
        child processes and you have forgotten to use the proper idiom
        in the main module:

            if __name__ == '__main__':
                freeze_support()
                ...

        The "freeze_support()" line can be omitted if the program
        is not going to be frozen to produce an executable.

您也可以在 POSIX 操作系统中使用 spawn 来模仿您在 Windows 上看到的行为:

import random
import os
from multiprocessing import Process, set_start_method
import platform

num = random.randint(0, 100)

def show_num():
    print("pid:{}, num is {}".format(os.getpid(), num))

if __name__ == '__main__':
    print(platform.system())
    # change the start method for new processes to spawn
    set_start_method("spawn")
    print("pid:{}, num is {}".format(os.getpid(), num))
    p = Process(target=show_num)
    p.start()
    p.join()
    print('Parent Process Stop')

输出:

Linux
pid:26835, num is 41
pid:26839, num is 13
Parent Process Stop

关于python - Python 中的多处理问题。 Windows 与 Linux,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55179311/

相关文章:

linux - Lynx 对 Google 搜索的请求不起作用

c++ - 为什么计算出的可用和总驱动器空间上限为 2G?

python - 子进程.Popen() : hide the cmd shell

python - 将数据库连接作为参数传递给方法是一种好习惯吗?

python - 将值传递给我的 Python 脚本的 procmal 配方

linux - 如何在c中创建一个窗口?

python - Grep 查找包含 [] 的特定句子

python - 如何使用 python 使用位移运算符找出以 2 为基数的数字的某个数字?

windows - NPM 安装 (Windows) 抛出 .SLN 错误...?