簡體   English   中英

我可以在 Pool.imap 調用的 function 中使用多處理隊列嗎?

[英]Can I use a multiprocessing Queue in a function called by Pool.imap?

我正在使用 python 2.7,並嘗試在自己的進程中運行一些 CPU 繁重的任務。 我希望能夠將消息發送回父進程,以使其了解進程的當前狀態。 多處理隊列似乎很適合這個,但我不知道如何讓它工作。

所以,這是我的基本工作示例,不使用隊列。

import multiprocessing as mp
import time

def f(x):
    return x*x

def main():
    pool = mp.Pool()
    results = pool.imap_unordered(f, range(1, 6))
    time.sleep(1)

    print str(results.next())

    pool.close()
    pool.join()

if __name__ == '__main__':
    main()

我試過以多種方式傳遞隊列,但他們收到錯誤消息“RuntimeError:隊列對象只能通過繼承在進程之間共享”。 這是我根據我發現的較早答案嘗試的方法之一。 (我在嘗試使用 Pool.map_async 和 Pool.imap 時遇到同樣的問題)

import multiprocessing as mp
import time

def f(args):
    x = args[0]
    q = args[1]
    q.put(str(x))
    time.sleep(0.1)
    return x*x

def main():
    q = mp.Queue()
    pool = mp.Pool()
    results = pool.imap_unordered(f, ([i, q] for i in range(1, 6)))

    print str(q.get())

    pool.close()
    pool.join()

if __name__ == '__main__':
    main()

最后,0 適應度方法(使其全局化)不會生成任何消息,它只是鎖定。

import multiprocessing as mp
import time

q = mp.Queue()

def f(x):
    q.put(str(x))
    return x*x

def main():
    pool = mp.Pool()
    results = pool.imap_unordered(f, range(1, 6))
    time.sleep(1)

    print q.get()

    pool.close()
    pool.join()

if __name__ == '__main__':
    main()

我知道它可能會直接與 multiprocessing.Process 一起使用,並且還有其他庫可以實現這一點,但我不想放棄非常適合的標准庫函數,直到我確定這不僅僅是我所缺少的知識使我無法利用它們。

謝謝。

訣竅是將Queue作為參數傳遞給初始化程序。 似乎可以與所有Pool調度方法一起使用。

import multiprocessing as mp

def f(x):
    f.q.put('Doing: ' + str(x))
    return x*x

def f_init(q):
    f.q = q

def main():
    jobs = range(1,6)

    q = mp.Queue()
    p = mp.Pool(None, f_init, [q])
    results = p.imap(f, jobs)
    p.close()

    for i in range(len(jobs)):
        print q.get()
        print results.next()

if __name__ == '__main__':
    main()

使用fork啟動方法(即,在 Unix 平台上),您不需要在最佳答案中使用該初始化程序技巧

只需將mp.Queue定義為全局變量,它就會被子進程正確繼承。

OP 的示例在 Linux 上使用 Python 3.9.7 運行良好(代碼略有調整):

import multiprocessing as mp
import time

q = mp.Queue()


def f(x):
    q.put(str(x))
    return x * x


def main():
    pool = mp.Pool(5)
    pool.imap_unordered(f, range(1, 6))
    time.sleep(1)

    for _ in range(1, 6):
        print(q.get())

    pool.close()
    pool.join()


if __name__ == '__main__':
    main()

Output:

2
1
3
4
5

已經 12 年了,但我想確保遇到這個問題的任何 Linux 用戶都知道只有在您不能使用 fork 時才需要最佳答案的技巧

暫無
暫無

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

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