簡體   English   中英

從 multiprocessing.Pool 調用的函數退出的正確方法?

[英]Right way to exit from function called by multiprocessing.Pool?

如何退出名為 my multiprocessing.Pool的函數

這是我正在使用的代碼示例,當我在終端中使用它作為腳本時,當我設置退出函數worker的條件時,它會停止並且不退出。

def worker(n):
    if n == 4:
        exit("wrong number")  # tried to use sys.exit(1) did not work
    return n*2

def caller(mylist, n=1):
    n_cores = n if n > 1 else multiprocessing.cpu_count()
    print(n_cores)
    pool = multiprocessing.Pool(processes=n_cores)
    result = pool.map(worker, mylist)
    pool.close()
    pool.join()
    return result

l = [2, 3, 60, 4]
myresult = caller(l, 4)

正如我所說,我認為您不能從工作進程退出運行主腳本的進程。

您還沒有確切解釋為什么要這樣做,所以這個答案是一個猜測,但也許引發自定義Exception並在顯式中處理它, except如下所示, except將是解決該限制的可接受方法。

import multiprocessing
import sys

class WorkerStopException(Exception):
    pass

def worker(n):
    if n == 4:
        raise WorkerStopException()
    return n*2

def caller(mylist, n=1):
    n_cores = n if n > 1 else multiprocessing.cpu_count()
    print(n_cores)
    pool = multiprocessing.Pool(processes=n_cores)
    try:
        result = pool.map(worker, mylist)
    except WorkerStopException:
        sys.exit("wrong number")
    pool.close()
    pool.join()
    return result

if __name__ == '__main__':
    l = [2, 3, 60, 4]
    myresult = caller(l, 4)

運行時顯示的輸出:

4
wrong number

4是我的系統擁有的 CPU 數量。)

pool.map是,只有所有任務完成,它才會從子進程中引發異常。 但是您的評論聽起來像是在任何過程中檢測到錯誤值后立即中止所有處理。 這將是pool.apply_async的工作。

pool.apply_async提供error_callbacks ,您可以使用它來讓池終止。 工作人員將按項目而不是像pool.map變體那樣按塊提供,因此您有機會提前退出每個處理過的參數。

我基本上是從這里重用我的答案:

from time import sleep
from multiprocessing import Pool

def f(x):
    sleep(x)
    print(f"f({x})")
    if x == 4:
        raise ValueError(f'wrong number: {x}')
    return x * 2

def on_error(e):
    if type(e) is ValueError:
        global terminated
        terminated = True
        pool.terminate()
        print(f"oops: {type(e).__name__}('{e}')")


def main():
    global pool
    global terminated

    terminated = False

    pool = Pool(4)
    results = [pool.apply_async(f, (x,), error_callback=on_error)
               for x in range(10)]
    pool.close()
    pool.join()

    if not terminated:
        for r in results:
            print(r.get())


if __name__ == '__main__':
    main()

輸出:

f(0)
f(1)
f(2)
f(3)
f(4)
oops: ValueError('wrong number: 4')

Process finished with exit code 0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM