解决jupyter使用多线程multiprocessing可运行不报错的问题

某个项目,需要使用多进程以加快速度,之前一直没用过多进程,Pycharm可以跑,但需要在jupyter上运行,出现的问题是:程序一直在运行中,但是没有输出结果

jupyter notebook/lab中直接使用多进程的话,虽然在界面上不会报错,但一直会处于运行状态,去查看命令行的话会看到报错: AttributeError: Can’t get attribute ‘XXX’ on <module ‘main’ >,由于某些原因Pool不能始终使用未在导入的模块中定义的对象

根据上一篇博客中得到的一些知识点,实际上这个地方:在linux中使用的是fork的方式,可以复制公共变量和方法到新开启的进程中,但是windows中是重建一个新的进程(全新),在进程中并不存在公共的变量和方法,所以会出现这个问题,未能导入模块中定义的对象

② 运行时报错: AttributeError: module ‘main’ has no attribute ‘spec’,这时需要在if __name__ == __main__:下面加上: spec = “ModuleSpec(name=‘builtins’, loader=<class ‘_frozen_importlib.BuiltinImporter’>)”

jupyter只能跟踪主进程,没法跟踪子进程,网上有一些其他的解决办法,但个人觉得最简单的还是将代码打包成py文件,再让jupyter执行这个文件

image.png

我基本上是在使用多处理模块,但我仍在学习多处理功能.我正在使用达斯蒂·菲利普斯(Dusty Phillips)编写的书,而这则代码属于该书.

import multiprocessing  
import random
from multiprocessing.pool import Pool

def prime_factor(value):
    factors = []
    for divisor in range(2, value-1):
        quotient, remainder = divmod(value, divisor)
        if not remainder:
            factors.extend(prime_factor(divisor))
            factors.extend(prime_factor(quotient))
            break
        else:
            factors = [value]
    return factors

if __name__ == '__main__':
    pool = Pool()
    to_factor = [ random.randint(100000, 50000000) for i in range(20)]
    results = pool.map(prime_factor, to_factor)
    for value, factors in zip(to_factor, results):
        print("The factors of {} are {}".format(value, factors))
复制代码

在Windows PowerShell上(不在jupyter笔记本上),我看到以下内容

Process SpawnPoolWorker-5:
Process SpawnPoolWorker-1:
AttributeError: Can't get attribute 'prime_factor' on <module '__main__' (built-in)>
复制代码

我不知道为什么该单元永远不会停止运行?

解决方案

在Jupyter笔记本电脑中,问题似乎与设计理念不同.因此,我们必须将函数(prime_factor)写入另一个文件,然后导入该模块.此外,我们必须注意调整.例如,就我而言,我已将该函数编码到一个名为defs.py

的文件中.

def prime_factor(value):
    factors = []
    for divisor in range(2, value-1):
        quotient, remainder = divmod(value, divisor)
        if not remainder:
            factors.extend(prime_factor(divisor))
            factors.extend(prime_factor(quotient))
            break
        else:
            factors = [value]
    return factors
复制代码

然后在jupyter笔记本中我写了以下几行

import multiprocessing  
import random
from multiprocessing import Pool
import defs



if __name__ == '__main__':
    pool = Pool()
    to_factor = [ random.randint(100000, 50000000) for i in range(20)]
    results = pool.map(defs.prime_factor, to_factor)
    for value, factors in zip(to_factor, results):
        print("The factors of {} are {}".format(value, factors))
复制代码

这解决了我的问题

image.png

猜你喜欢

转载自juejin.im/post/7017712084892794910