代码先锋网 代码片段及技术文章聚合

在spyder、Jupyter Notebook 中使用multiprocessing创建多进程不仅不会同时执行而且会卡死的原因详解

技术标签: python  pycharm  jupyter  ide

这是因为multiprocessing模块不支持交互模式!!!。

必须在 cmd 里头输入 python xxx.py 来运行,

才可以看到子进程的执行。

原因:spyder、Jupyter Notebook使用的stdout和windows不支持forking,所以无法打印子进程内容。

选择pycharm的理由
一直用Anaconda自带的Spyder做开发,尽管界面漂亮,但是写代码过程中遇到三个难受的问题:

1. 没有目录树:做开发时,打开的文件很快就挤满了标签栏;

补充:谢谢评论中的提醒,右键点击标签页的左上角选择“set console working directory”,可在File explorer找到目录结构。

2. 子进程输出丢失:实现多进程时,进程内部的print无法打印;

3. 在实现多进程时运行了一下multiprocessing.Queue(),迟迟没有成功(在ipyhon单句运行就没问题)。

以上问题1还可以忍受,但是目前的项目避不开2和3,所以决定换pycharm试一下:

经测试,pycharm可以解决问题1、问题2,解决问题3时我改为用pool,pycharm可运行成功。

Python多进程multiprocessing在Windows的Dos下或者Idle运行不了会出错,

打成exe包双击后会一直打开exe,导致内存占满,在linux下确没有问题,

在Pycharm下运行也不会有问题,经过各种查阅资料,终于解决了这个Bug

只要添加在main入口下添加 multiprocessing.freeze_support() 就可以了,

multiprocessing.Process()尽量规范为在main下面(里面)运行!!

if __name__ == "__main__":
    multiprocessing.freeze_support()

Python使用缩进对齐组织代码的执行,所以所有没有缩进的代码(非函数定义和类定义),都会在载入时自动执行,这些代码,可以认为是Python的main函数。

@什么是multiprocessing?

Unix/Linux操作系统提供了一个fork()系统调用,可以用来创建进程。它非常特殊。普通的函数调用,调用一次,返回一次,但是fork()调用一次,返回两次,因为操作系统自动把当前进程(称为父进程)复制了一份(称为子进程),然后,分别在父进程和子进程内返回。

但是由于Windows没有fork调用,所以为了支持跨平台,pytho搞了个跨平台multiprocessing实现多进程,但是尽管如此在windows上和linux上,用multiprocessing实现方式还是不太一样。在windows上会有一个import创建进程的模块的操作,而linux上就没有,基于fork。在windows上,子进程会自动import启动它的这个文件,而在import的时候是会自动执行这些语句的(意思说子进程会复制并以import的形式导入执行主进程中代码,如果你把要执行的代码放到了if__name__ == "__main__"中,那么这个时候因为是import,所以这个时候就不会执行该代码了)。所以创建进程的操作要用if __name__ == "__main__":保护起来,否则就会递归创建进程,或者出其它什么错误。

@@@@@@@@@@@@@@解决办法还有三种:

(1)Using the logging module. This would encompass creating and logging all messages to one or several files. Using a single log-file may lead to the problem that the output is slightly garbled since the processes would write concurrently to the file. Using a single file per process could solve this.


import multiprocessing
 
def worker(num):
    """Returns the string of interest"""
    return "worker %d" % num
 
def main():
    pool = multiprocessing.Pool(4)
    results = pool.map(worker, range(10))
 
    pool.close()
    pool.join()
 
    for result in results:
        # prints the result string in the main process
        print(result)
 
if __name__ == '__main__':
    # Better protect your main function when you use multiprocessing

(2)Not using print within the child processes, but simply returning the result to the main process. Either by using a queue (or multiprocessing.Manager().Queue() since forking is not possible) or more simply by relying on the multiprocessing Pool's map functionality, see example below.

def main():
    pool = multiprocessing.Pool(4)
    results = pool.imap_unordered(worker, range(10))
 
    for result in results:
        # prints the result string in the main process as soon as say are ready
        # but results are now no longer in order!
        print(result)
 
    # The pool should join after printing all results
    pool.close()
    pool.join()

(2)​​​​​(3)Python Jupyter notebook 运行 multiprocessing 跑不了的问题_e274794140的专栏-CSDN博客_jupyter notebook 多进程

from multiprocessing import Pool
from functools import partial
import inspect
 
def parallal_task(func, iterable, *params):
 
    with open(f'./tmp_func.py', 'w') as file:
        file.write(inspect.getsource(func).replace(func.__name__, "task"))
 
    from tmp_func import task
 
    if __name__ == '__main__':
        func = partial(task, params)
        pool = Pool(processes=8)
        res = pool.map(func, iterable)
        pool.close()
        return res
    else:
        raise "Not in Jupyter Notebook"

def long_running_task(params, id):
    # Heavy job here
    return params, id
 
data_list = range(8)
 
for res in parallal_task(long_running_task, data_list, "a", 1, "b"):
    print(res) 

 【Python有坑系列】python多进程,函数内print的内容没有打印出来_小白兔de窝-CSDN博客_python 多进程不打印 process - Simple Python Multiprocessing function in Spyder doesn't output results - Stack Overflow

@@@@@@@@@@在jupyter中多进程 为什么运行了没反应? - 知乎 (zhihu.com)

%%writefile temp\1.py

#上方代码用于将以下代码保存为py文件
from multiprocessing import Process

import os


def func():

#     os.getpid()获取当前进程id     os.getppid()获取父进程id
    print('func',os.getpid(), os.getppid())


if __name__ == '__main__':

    print('__main__',os.getpid(), os.getppid())

    p = Process(target=func,)

    p.start()

 分两个步骤。

1、%%writefile temp\1.py
把上面这行代码加在代码块的【顶】部。目的是将jupyter中的代码块保存为temp文件夹中的py文件(文件夹不存在会报错)。

2、然后就可以在jupyter中运行这个py文件(感叹号+py文件路径)。

! temp\1.py

版权声明:本文为xuexijiaoliu原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xuexijiaoliu/article/details/122521908

智能推荐

jupyter notebook 创建密码

jupyter notebook 创建密码 产生jupyter notebook的配置文件: 生成的配置文件位置为:~/.jupyter/jupyter_notebook_config.py 打开jupyter,新建一个notebook,创建密码以及生成密码的sha1**,所需代码如下: 输入一遍你想设置的密码,然后再输入一遍确认,记录下生成的sha1**值。形式如:‘sha1:xxx...

Jupyter Notebook使用技巧

1. 改变Jupyter Notebook的主题 安装 列出所有主题 更换为指定的主题 恢复为默认主题  ...

Jupyter notebook使用

欢迎关注天下博客:http://blog.genesino.com/2017/12/jupyter/ Jupyter notebook (Ipython notebook)是集代码、结果、文档三位一体的文学化可重复程序文档。支持40多种程序语言,Python为原生语言。如果安装了Anaconda,就会自动包含。Anaconda的安装见之前的文档Linux学习 - Conda软件安装方法](http...

远程使用Jupyter Notebook

远程使用Jupyter Notebook 生成密码用来登录 python终端下: 创建配置文件 其中: 另外,像ssh一样,我的校园网下仍然是只能用有线,并且要关禁用无线。...

Jupyter Notebook使用

Magic 关键字 Magic 关键字是可以在单元格中运行的特殊命令,能让你控制 notebook 本身或执行系统调用(例如更改目录)。例如,在 notebook 中可以使用 %matplotlib 将 matplotlib 设置为以交互方式工作。 Magic 命令的前面带有一个或两个百分号(% 或 %%),分别对应行 Magic 命令和单元格 Magic 命令。行 Magic 命令仅应用于编写 ...

猜你喜欢

远程使用jupyter notebook

需求 为了在远程服务器上运行python程序。主要是因为服务器长期运行,一些下载数据的程序可以在服务上跑,不影响客户机的使用,尽可能提高服务器的使用率。 当然也可以直接使用.py文件。但使用notebook比较方便。 解决 1. 在服务器上安装miniconda. 下载好.sh文件。 2. 在服务器上设置jupyter notebook 我是先单独安装的jupyter notebook,后来才安装...

jupyter notebook 使用

print(‘Hello World!’)...

Jupyter NoteBook使用问题

问题: 解决方案: 问题一般是:iPython 和 prompt-toolkit版本不一致 对于版本iPython 7.7.0:...

Jupyter Notebook使用

文|Seraph 参数 含义 –port 指定端口 –ip 设置IP 02 | 配置远程Jupyter Notebook服务 生成**并获取 修改配置文件~/.jupyter/jupyter_notebook_config.py如下: 99 | 问题解决 启动Jupyter Notebook时提示:OSError: [Errno 99] Cannot assign requ...

jupyter notebook 使用技巧

jupyter notebook 使用技巧 1、jupyter_contrib_nbextensions 计时插件 实现每个cell 运算时间显示 安装时需关闭 jupyter 2、Jupyter Notebook修改起始路径方法 打开 cmd ,进入你安装的anaconda目录下,输入命令 jupyter notebook --generate-config,将生成jupyter_noteboo...