【问题标题】:why is a string printing 3 times instead of 1 when using time.sleep with multiprocessing imported?为什么使用 time.sleep 导入多处理时字符串打印 3 次而不是 1 次?
【发布时间】:2021-08-23 20:20:04
【问题描述】:

所以当我在与我的 print 相同的代码中导入 multiprocessing 后跟 time.sleep 时,它将打印字符串 3 次,而不是我请求的 1 次。我想知道为什么会发生这种情况以及如果可能的话如何解决这个问题,提前谢谢你。我的代码如下。

import time
import multiprocessing

print('teeeest')
time.sleep(3)

def test1():
    print('test1')
def test2():
    print('test2')

if __name__ == '__main__':
    p1 = multiprocessing.Process(target=test1)
    p2 = multiprocessing.Process(target=test2)
    p1.start()
    p2.start()
    p1.join()
    p2.join()

而代码的结果如下:

teeeest
teeeest
teeeest
test1
test2

(注意“test1”和“test2”按预期同时发送)

【问题讨论】:

  • @jsbueno Macos 做同样的事情。
  • MacOS 没有工作的“fork”吗?
  • MacOS 不只使用 fork Linux。 @jsbueno
  • 是的 - 我检查了一下 - 他们在 Python 3.8 上不再使用 fork。

标签: python multiprocessing


【解决方案1】:

当您使用多处理时,Python 会使用全新的解释器副本创建一个全新的进程,并从顶部再次开始运行您的文件。任何你不想让每个孩子都做的事情都需要放在你的 if __name__ == '__main__': 块中。

【讨论】:

  • 嗯。当我按原样运行代码时,我只会打印一次teeeest
  • Linux 的行为不同,因为它可以使用fork 克隆进程并从该位置继续运行。
  • 哦,我没想到答案这么快。非常感谢,这真的很有帮助。我对多处理的工作原理有了新的认识,并且可以解决我遇到的其他问题。 @TimRoberts 不过,我知道 Linux 是如何分叉的。
  • 有趣!我确实在 Linux 上运行过它。
【解决方案2】:

当您使用多处理时,Python 会创建一个新进程 - 在 Microsoft Windows 操作系统中,新进程拥有与原始进程相同的已加载模块的唯一方法是全部加载它们 - 并且 Python 模块会在其上执行正在加载。

在其他操作系统(MacO、Linux 等)上,Python 使用“fork”系统调用创建正在运行的进程的“克隆”,并且不必再次运行和执行模块.

Windows 下的行为是任何使用多处理运行的代码必须if __name__ == "__main__": 表达式保护的动机:在复制的进程上,__name__ 的内容不再是__main__,因为前一个主文件是由子进程上的多处理机制导入的。

更新:似乎从 Python 3.8 开始,在 MacOS 上默认使用 Spawn,而不是 fork - 所以在 Mac 上你会得到相同的行为。 (看这里https://www.reddit.com/r/learnpython/comments/g5372v/multiprocessing_with_fork_on_macos/

【讨论】:

    猜你喜欢
    • 2019-03-15
    • 2016-07-11
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 2020-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多