【问题标题】:Multiprocessing in python3 get different values when running on mac and linuxpython3中的多处理在mac和linux上运行时得到不同的值
【发布时间】:2020-09-03 20:48:46
【问题描述】:

在 Mac 和 Linux 上运行时,Python 3 中的多处理得到不同的值。

例如,当 fork 主进程中的变量值应该被克隆到子进程中。但是经过测试,Linux 的结果与 Mac 不同。

这里是代码

#!/usr/bin/env python
# coding=utf-8
import multiprocessing

test_temp = "a"


def check_value_in_other_process():
    print(f"[{multiprocessing.current_process().name}] test_temp={test_temp}")


def change_value():
    global test_temp
    test_temp = "b"


if __name__ == '__main__':

    print(f"[{multiprocessing.current_process().name}] origin test_temp={test_temp}")
    change_value()
    print(f"[{multiprocessing.current_process().name}] changed test_temp={test_temp}")

    pool = multiprocessing.Pool(4)
    pool.apply_async(func=check_value_in_other_process)
    pool.close()
    pool.join()

在Linux上,我用Debian 9和CentOS 8测试,结果是

[MainProcess] origin test_temp=a
[MainProcess] changed test_temp=b
[ForkPoolWorker-1] test_temp=b

在mac上,我用mac os 14和mac os 15测试,结果是:

[MainProcess] origin test_temp=a
[MainProcess] changed test_temp=b
[SpawnPoolWorker-2] test_temp=a

可能是 ForkPoolWorker 和 SpawnPoolWorker 造成的差异?

查了一下,发现创建进程有3种方式:spawn、fork、forkserver。 所以我补充说:

multiprocessing.set_start_method('fork')

Linux 和 Mac 得到相同的结果 但是:

  1. 为什么 mac 会采取不同的默认行为?
  2. 如何在我的项目中设置默认行为?

【问题讨论】:

    标签: python python-3.x process operating-system python-3.8


    【解决方案1】:

    我在 macOS 10.15 和 Python 3.6.5 上看到了前一个输出(你在 Linux 上看到的那个),结果他们在 Python 3.8 中改变了这种行为(你必须运行 3.8 或更高版本):

    https://docs.python.org/3/library/multiprocessing.html#contexts-and-start-methods

    在 3.8 版中更改:在 macOS 上,spawn start 方法现在是默认设置。 fork start 方法应该被认为是不安全的,因为它可能导致子进程崩溃。见bpo-33725

    spawn模式下,子进程只会继承那些运行进程对象run()方法所必需的资源。特别是,不会继承父进程中不必要的文件描述符和句柄。在 fork 模式下(Unix 的默认模式),父进程的所有资源都由子进程继承。

    回答您的第二个问题:建议在 macOS 上使用 fork(如上所述),因此如果您必须在两个平台上具有完全相同的行为,坚持spawn

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-09
      • 1970-01-01
      • 2021-04-26
      相关资源
      最近更新 更多