簡體   English   中英

有沒有辦法在嵌套函數或模塊中使用 multiprocessing.pool?

[英]Is there any way to use multiprocessing.pool within a nested function or module?

感謝您查看此內容。 我承認我已經在 python 中進行了 1 周的並行處理,所以如果我錯過了一個明顯的解決方案,我深表歉意。 我有一段代碼,我想運行 mp.pool() 的幾個不同實例。 那些在主 .py 文件上的調用工作正常,但是當我嘗試將它們添加到模塊中的函數時,我沒有從它們中得到任何輸出。 該應用程序只是運行通過它並繼續。 我認為它可能與這篇文章有關,但它沒有給出關於完成我需要的替代方法的任何想法。 在一個簡單示例中工作的代碼是這樣的:

import multiprocessing as mp
def multiproc_log_result(retval):
    results.append(retval)
    if len(results) % (10 // 10) == 0:
        print('{0}% done'.format(100 * len(results) / 10))

def meat():
    print 'beef'
    status = True
    return status
results = []
pool = mp.Pool(thread_count)
for x in range(10):
    pool.apply_async(meat, callback=multiproc_log_result)
pool.close()
pool.join()


def veggie():
    print 'carrot'
    status = True
    return status

results = []
pool = mp.Pool(thread_count)
for x in range(10):
    pool.apply_async(veggie, callback=multiproc_log_result)
pool.close()
pool.join()

不起作用的代碼是:

import multiprocessing as mp
def multiproc_log_result(retval):
    results.append(retval)
    if len(results) % (10 // 10) == 0:
        print('{0}% done'.format(100 * len(results) / 10))

def meat():
    print 'beef'
    status = True
    return status
results = []
pool = mp.Pool(thread_count)
for x in range(10):
    pool.apply_async(meat, callback=multiproc_log_result)
pool.close()
pool.join()

def nested_stupid_fn():
    def multiproc_log_result(retval):
        results.append(retval)
        if len(results) % (10 // 10) == 0:
            print('{0}% done'.format(100 * len(results) / 10))

    def veggie():
        print 'carrot'
        status = True
        return status

    results = []
    pool = mp.Pool(thread_count)
    for x in range(10):
        pool.apply_async(veggie, callback=multiproc_log_result)
    pool.close()
    pool.join()
nested_stupid_fn()

最終,我希望那個不起作用的例子通過將它存在於單獨模塊中的另一個函數中而被刪除。 因此,當我導入模塊 packngo 並將其用作 packngo.basic_packngo(inputs) 並在其中某處包含 nest 函數的內容時,它們將運行。 任何幫助將不勝感激。 :DI 是一個非常簡單的人,所以如果你能像對孩子一樣解釋,也許它會沉入我的腦海!

您鏈接的另一個問題有解決方案,只是沒有說明:您不能使用嵌套函數作為multiprocessing.Pool上的apply* / *map*系列方法的func參數。 它們適用於multiprocessing.dummy.Pool ,因為multiprocessing.dummy由可以直接傳遞函數引用的線程支持,但multiprocessing.Pool必須pickle 函數,並且只能pickle 具有可導入名稱的函數。 如果您檢查嵌套函數的名稱,它類似於modulename.outerfuncname.<locals>.innerfuncname ,並且<locals>組件使其無法導入(這通常是一件好事;利用嵌套的嵌套函數通常在關閉范圍內具有臨界狀態,僅導入就會丟失)。

以嵌套方式定義callback函數非常好,因為它們是在父進程中執行的,它們不會發送給工作進程。 在您的情況下,只有回調依賴於閉包范圍,因此將func ( veggie ) 移出全局范圍是完全沒問題的,將您的packngo模塊定義為:

def veggie():
    print 'carrot'
    status = True
    return status

def nested_stupid_fn():
    def multiproc_log_result(retval):
        results.append(retval)
        if len(results) % (10 // 10) == 0:
            print('{0}% done'.format(100 * len(results) / 10))

    results = []
    pool = mp.Pool(thread_count)
    for x in range(10):
        pool.apply_async(veggie, callback=multiproc_log_result)
    pool.close()
    pool.join()
nested_stupid_fn()

是的,這意味着veggie成為相關模塊的公共成員。 如果你想表明它應該被視為一個實現細節,你可以用下划線 ( _veggie ) 作為前綴,但它必須是全局的才能與multiprocessing.Pool一起使用。

好吧,我認為問題是在multiproc_log_result的范圍內,變量results不存在。 因此,您應該做的是將異步調用的結果直接附加到結果中。 但是,您將無法跟蹤進度(我猜無法在類外直接共享回調函數的全局變量)

from multiprocessing.pool import ThreadPool

def nested_stupid_fn():
    def multiproc_log_result(retval):
        results.append(retval)

    def veggie():
        print 'carrot'
        status = True
        return status

    results = []
    pool = ThreadPool(thread_count)
    for x in range(10):
        results.append(pool.apply_async(veggie))

    pool.close()
    pool.join()

    results = [result.get() for result in results]  # get value from async result

    ...then do stuff with results

暫無
暫無

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

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