Jupyter中使用multiprocessing时Print与异常无法显示的问题
Jupyter Notebook中使用multiprocessing无法看到输出的解决方法
问题场景
在Jupyter里用multiprocessing时,已经把函数放到单独文件里,比如:
def trial_hello(): print('Hello World')
或者抛出异常的函数:
def trial_excp(): raise Exception
但从Notebook导入这些函数,创建Process实例调用start()和join()后,看不到预期的打印内容或异常信息;直接调用函数却能正常显示。Notebook里的代码如下:
from ipynb.fs.full.trial import trial_hello from multiprocessing import Process p1 = Process(target=trial_hello) p2 = Process(target=trial_hello) p3 = Process(target=trial_hello) p1.start() p2.start() p3.start() p1.join() p2.join() p3.join()
解决办法
1. 强制使用spawn启动方式
Jupyter的环境和multiprocessing默认的fork启动方式(Linux/macOS下)存在冲突,导致子进程的输出无法被捕获。在创建任何进程实例前,添加以下代码:
import multiprocessing multiprocessing.set_start_method('spawn')
注意:这段代码整个Notebook只能执行一次,重复运行会报错。
2. 用队列捕获输出或异常
如果需要获取子进程的打印内容或异常,通过multiprocessing.Queue来传递信息:
- 先修改单独文件里的函数,把输出/异常存入队列:
def trial_hello(queue): queue.put('Hello World') def trial_excp(queue): try: raise Exception("测试异常") except Exception as e: queue.put(str(e))
- 然后在Notebook中接收队列里的内容:
import multiprocessing multiprocessing.set_start_method('spawn') # 建议从.py文件导入,比如from trial import trial_hello, trial_excp from ipynb.fs.full.trial import trial_hello, trial_excp queue = multiprocessing.Queue() p1 = Process(target=trial_hello, args=(queue,)) p2 = Process(target=trial_hello, args=(queue,)) p3 = Process(target=trial_excp, args=(queue,)) p1.start() p2.start() p3.start() p1.join() p2.join() p3.join() # 读取所有队列内容 while not queue.empty(): print(queue.get())
3. 改用普通.py文件存放函数
尽量不要从.ipynb文件导入函数,把函数放到后缀为.py的普通Python文件中,比如创建trial.py,然后在Notebook里用from trial import trial_hello导入,能避免很多环境兼容问题。
内容的提问来源于stack exchange,提问作者tewerty
相关产品推荐
相关产品推荐

