python - 如何在继续之前等待所有 multiprocessing.Processes 完成?

标签 python windows join multiprocessing

我正在学习 Python multiprocessing并试图了解如何让我的代码等待所有进程完成,然后继续执行其余代码。我以为 join()方法应该可以完成这项工作,但是我的代码输出不是我使用它所期望的。
这是代码:

from multiprocessing import Process
import time 

def fun():

    print('starting fun')
    time.sleep(2)
    print('finishing fun')

def fun2():

    print('starting fun2')
    time.sleep(5)
    print('finishing fun2')

def fun3():

    print('starting fun3')
    print('finishing fun3')   

if __name__ == '__main__':
    processes = []
    print('starting main')
    for i in [fun, fun2, fun3]:
        p = Process(target=i)
        p.start()
        processes.append(p)
    for p in processes:
        p.join()  
    print('finishing main')

g=0
print("g",g)
我预计 if __name__ == '__main__': 下的所有进程在行前结束g=0print(g)被调用,所以这样的事情是预料之中的:
starting main
starting fun2
starting fun
starting fun3
finishing fun3
finishing fun
finishing fun2
finishing main
g 0
但实际输出表明我对 join() 有一些不明白的地方。 (或 multiprocessing 一般):
starting main
g 0
g 0
starting fun2
g 0
starting fun
starting fun3
finishing fun3
finishing fun
finishing fun2
finishing main
g 0
问题是:如何编写先完成所有进程的代码,然后在没有多处理的情况下继续执行代码,以便获得前一个输出?我从 Windows 上的命令提示符运行代码,以防万一。

最佳答案

等待Process完成:
你可以Process.join你的 list ,比如

import multiprocessing
import time

def func1():
    time.sleep(1)
    print('func1')

def func2():
    time.sleep(2)
    print('func2')

def func3():
    time.sleep(3)
    print('func3')

def main():
    processes = [
        multiprocessing.Process(target=func1),
        multiprocessing.Process(target=func2),
        multiprocessing.Process(target=func3),
    ]
    for p in processes:
        p.start()

    for p in processes:
        p.join()

if __name__ == '__main__':
    main()
但是,如果您正在考虑让您的流程更加复杂,请尝试使用 Pool :
import multiprocessing
import time

def func1():
    time.sleep(1)
    print('func1')

def func2():
    time.sleep(2)
    print('func2')

def func3():
    time.sleep(3)
    print('func3')

def main():
    result = []
    with multiprocessing.Pool() as pool:
        result.append(pool.apply_async(func1))
        result.append(pool.apply_async(func2))
        result.append(pool.apply_async(func3))

        for r in result:
            r.wait()

if __name__ == '__main__':
    main()
More info on Pool
关于为什么 g0 打印多次:
发生这种情况是因为您正在使用 spawnforkserver设置您的Processg0print声明在函数或 __main__ 之外如果阻塞。
来自 the docs :

Make sure that the main module can be safely imported by a new Python interpreter without causing unintended side effects (such a starting a new process).

(...)

This allows the newly spawned Python interpreter to safely import the module and then run the module’s foo() function.

Similar restrictions apply if a pool or manager is created in the main module.


它基本上是再次解释,因为它正在导入您的 .py文件作为模块。

关于python - 如何在继续之前等待所有 multiprocessing.Processes 完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64229307/

相关文章:

python - pytest 如何同时使用 getoption 和 parameterize

python - 如何将列表转换为 REST 的分页 JSON 响应?

windows - 使用 Wix 安装应用程序以在 Windows 关机时运行

php - 将 JOIN SQL 查询序列化为 JSON 的最佳方法

sql - 根据最大id连接表

python - pandas DataFrame 将代码或标签转换为分类

python - 无法在 Windows virtualenv 上安装 pycrypto

c++ - Windows高性能计数器的分辨率是多少?

windows - 如何在 Windows 主机上通过 FTP 删除 svn 文件夹

laravel - 如何为 laravel 验证器的自定义存在规则添加连接?