Jupyter笔记本中的Python多处理



我是Python中multiprocessing模块的新手,并使用Jupyter Notebooks。我尝试了以下来自PMOTW的代码段:

import multiprocessing
def worker():
    """worker function"""
    print('Worker')
    return
if __name__ == '__main__':
    jobs = []
    for i in range(5):
        p = multiprocessing.Process(target=worker)
        jobs.append(p)
        p.start()

当我按原样运行时,没有输出。

我还尝试过创建一个称为worker.py的模块,然后将其导入运行代码:

import multiprocessing
from worker import worker
if __name__ == '__main__':
    jobs = []
    for i in range(5):
        p = multiprocessing.Process(target=worker)
        jobs.append(p)
        p.start()

在这种情况下仍然没有输出。在控制台中,我看到以下错误(重复多次(:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:Program FilesAnaconda3libmultiprocessingspawn.py", line 106, in spawn_main
    exitcode = _main(fd)
  File "C:Program FilesAnaconda3libmultiprocessingspawn.py", line 116, in _main
    self = pickle.load(from_parent)
AttributeError: Can't get attribute 'worker' on <module '__main__' (built-in)>

但是,当代码保存为Python脚本并将其显示时,我将获得预期的输出。

我该怎么做才能直接从笔记本上运行此代码而不创建单独的脚本?

我对并行计算我相对较新,因此我可能有一些技术性是错误的。我的理解是:

jupyter笔记本电脑不使用multiprocessing,因为模块泡菜(序列化(数据要发送到进程。 multiprocessmultiprocessing的叉子,它使用DILL代替泡菜来序列数据,该数据允许其在Jupyter笔记本中使用。API是相同的,因此您唯一需要做的就是更改

import multiprocessing

to ...

import multiprocess

您可以很容易地使用简单的

安装multiprocess
pip install multiprocess

但是,您会发现您的流程仍然不会打印到输出中(尽管在Jupyter Labs中,他们将打印到服务器正在运行的终端(。我偶然发现了这篇文章,试图解决此问题,并在找出该方法时编辑这篇文章。

我在multiprocessingipykernel中都不是导出(Jupyter Notebook使用(,但是由于似乎没有人给出答案,所以我会告诉您我猜到了什么。我希望有人在稍后对此进行补充。

我猜您的Jupyter笔记本服务器正在Windows主机上运行。在多处理中,有三种不同的开始方法。让我们重点关注 spawn ,这是Windows上的默认值, fork ,UNIX上的默认值。

这是一个快速概述。

  • Spawn

    • (cpython(互动shell - 始终提出错误
    • 以脚本运行 - 仅在if __name__ == '__main'__中嵌套多处理代码
    • 时才能运行
  • fork

    • 总是好的

例如,

import multiprocessing
def worker():
    """worker function"""
    print('Worker')
    return
if __name__ == '__main__':
    multiprocessing.set_start_method('spawn')
    jobs = []
    for i in range(5):
        p = multiprocessing.Process(target=worker)
        jobs.append(p)
        p.start()

此代码在保存并作为脚本运行时起作用,但是在Python Interactive Shell中输入时会引起错误。这是Ipython内核的实现,我的猜测是它使用了某种交互式外壳,因此与 Spawn> Spawn (但请不要相信我(。


对于旁注,我将为您提供有关 Spawn fork 的一般想法。每个子过程都在多处理中运行不同的python解释器。特别是,使用 Spawn ,子过程启动了一个新的解释器,并从头开始导入必要的模块。很难在交互式外壳中导入代码,因此可能会引起错误。

fork 是不同的。使用FORK,一个子过程将复制主要过程,包括Python解释器的大多数运行状态,然后继续执行。此代码将帮助您理解该概念。

import os

main_pid = os.getpid()
os.fork()
print("Hello world(%d)" % os.getpid())  # print twice. Hello world(id1) Hello world(id2)
if os.getpid() == main_pid:
    print("Hello world(main process)")  # print once. Hello world(main process)

很像您,我遇到了属性错误。问题似乎与Jupyter处理多线程有关。我得到的最快的结果是遵循多处理示例。

,The Treadpool照顾了我的问题。

from multiprocessing.pool import ThreadPool as Pool
def worker():
    """worker function"""
    print('Workern')
    return

pool = Pool(4)
for result in pool.map(worker, range(5)):
    pass    # or print diagnostics

这对我在Mac上有效(无法在Windows上使用(:

import multiprocessing as mp
mp_start_count = 0
if __name__ == '__main__':
    if mp_start_count == 0:
        mp.set_start_method('fork')
        mp_start_count += 1

将功能保存到单独的python文件,然后将功能重新导入。

相关内容

  • 没有找到相关文章

最新更新