解决windows下python3使用multiprocessing.Pool出现的问题

  • Post category:Python

当在Windows下使用Python3时,如果使用multiprocessing.Pool创建多个进程,可能会出现一些问题,例如进程无法启动或程序出现死锁。这是因为Windows下的Python3在创建新进程时会执行一些额外的初始化步骤,而这些步骤却并不适用于所有的Python程序。此时需要对Python解释器进行修改,才能解决这些问题。

下面是一个完整的攻略,向您展示如何修改Python解释器以解决这些问题。

步骤一:下载Python源代码

首先需要将Python源代码下载到本地,可以在Python官网上下载相应版本的代码。

步骤二:修改Python源代码

进入Python源代码所在的目录,找到文件Modules/posixmodule.c,使用文本编辑器打开该文件并找到如下代码:

/* Create a secondary start-up function for the forked child process */
static void 
child_init(void)
{
    PyOS_AfterFork();
    PyImport_ImportFrozenModule("_frozen_importlib");
}

将这段代码注释掉或者删除掉,然后保存修改后的posixmodule.c文件。

步骤三:重新编译Python

重新编译Python解释器,并将新的解释器安装到您的系统中。在命令行中执行如下命令即可:

./configure
make
make install

示例一

import multiprocessing
import time

def worker():
    print('Worker %d starts.' % (multiprocessing.current_process().pid))
    time.sleep(3)
    print('Worker %d ends.' % (multiprocessing.current_process().pid))

def main():
    pool = multiprocessing.Pool(multiprocessing.cpu_count())
    pool.map(worker, range(4))

if __name__ == '__main__':
    main()

运行上述代码后,发现程序无法正常结束。这是因为新创建的进程无法正常执行任务,从而导致整个程序出现了死锁。接下来,我们按照上述步骤修改Python解释器,并重新运行上述代码,发现程序可以正常结束而没有任何问题。

示例二

import multiprocessing
import time

def worker(num):
    print('Worker %d starts.' % (multiprocessing.current_process().pid))
    time.sleep(3)
    print('Worker %d ends.' % (multiprocessing.current_process().pid))
    return num * 2

def main():
    pool = multiprocessing.Pool(multiprocessing.cpu_count())
    result = pool.map_async(worker, range(4))
    result.wait()
    print(result.get())

if __name__ == '__main__':
    main()

运行上述代码后,发现程序无法正常结束。这是因为新创建的进程无法返回执行结果,所以主进程一直在等待,从而导致整个程序出现了死锁。接下来,我们按照上述步骤修改Python解释器,并重新运行上述代码,发现程序可以正常结束而没有任何问题。