[英]python multiprocessing queue implementation
我無法理解如何在下面的多處理示例中實現隊列。 基本上,我希望代碼能夠:
1) 生成 2 個進程(完成)
2) 將我的 id_list 分成兩部分(完成)
3)讓每個進程遍歷打印出每個項目的列表,並且僅在完成列表后才關閉。 我知道我必須實施某種類型的排隊系統,並將其傳遞給每個工作人員,但我不確定該怎么做。 任何幫助將非常感激。
from multiprocessing import Pool,Queue
id_list = [1,2,3,4,5,6,7,8,9,10]
def mp_worker(record):
try:
print record
sleep(1)
except: pass
print "worker closed"
def mp_handler():
p = Pool(processes = 2) #number of processes
p.map(mp_worker, id_list) #devides id_list between 2 processes, defined above
p.close()
p.join()
mp_handler()
注意 - 代碼打印出“worker closed”10 次。 我希望這條語句只打印兩次(每個工人打印一次,在每個工人打印出 id_list 中的 5 個數字之后)
這對我有用(在 Python 3 上)。 我沒有使用池,而是生成了自己的兩個進程:
from multiprocessing import Process, Queue
from time import sleep
id_list = [1,2,3,4,5,6,7,8,9,10]
queue = Queue()
def mp_worker(queue):
while queue.qsize() >0 :
record = queue.get()
print(record)
sleep(1)
print("worker closed")
def mp_handler():
# Spawn two processes, assigning the method to be executed
# and the input arguments (the queue)
processes = [Process(target=mp_worker, args=(queue,)) for _ in range(2)]
for process in processes:
process.start()
print('Process started')
for process in processes:
process.join()
if __name__ == '__main__':
for id in id_list:
queue.put(id)
mp_handler()
盡管要處理的元素的長度是硬編碼的。 但它可能是 mp_worker 方法的第二個輸入參數。
使用 Pool 和 Queue 解決此問題的一種方法是
from time import sleep
from multiprocessing import Pool,Queue
id_list = [1,2,3,4,5,6,7,8,9,10]
def mp_worker(q):
try:
print(q.get())
sleep(.1)
except: pass
print ("worker closed")
if __name__ == "__main__":
q = Queue()
p = Pool(processes = 2) #number of processes
for x in id_list:
q.put(x)
p.map(mp_worker, id_list) #devides id_list between 2 processes, defined above
您必須通過放入代碼的主要部分並在函數中通過get從隊列中讀取值來向 Quene 添加 vaules
您在那里的打印語句會誤導您——工作進程不會在函數結束時終止。 事實上,工作進程在池關閉之前一直保持活動狀態。 此外, multiprocessing
已經負責將列表分解成塊並為您排隊每個任務。
至於你的另一個問題,如果你想在整個列表完成時觸發一個異步事件,通常你會向map_async
傳遞一個回調。 每個塊調用一次需要對內部進行一些處理,但如果你真的想要,你可以:
def mapstar_custom(args):
result = list(map(*args))
print "Task completed"
return result
...
pool._map_async(f, x, mapstar_custom, None, None, None).get()
編輯:我們似乎混淆了術語。 當我說 worker 時,我指的是池產生的進程,而您似乎指的是 Selenium 從這些進程中產生的進程(這不是您的問題)。 只打開一次 webdriver 很容易:如果你有pool.map(module.task, ...)
,那么在module.py
只需執行以下操作:
# ... selenium init here ...
def task(...):
# ... use webdriver ...
無論您分派該任務多少次,該模塊只會被池工作人員導入一次。 所以頂級 init 只會發生一次。
由於這是Python Multiprocessing Queue implementation
的最高 Google 結果,我將發布一個稍微更通用的示例。
考慮以下腳本:
import time
import math
import pprint
def main():
print('\n' + 'starting . . .' + '\n')
startTime = time.time()
my_list = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
result_list = []
for num in my_list:
result_list.append(squareNum(num))
# end for
elapsedTime = time.time() - startTime
print('result_list: ')
pprint.pprint(result_list)
print('\n' + 'program took ' + '{:.2f}'.format(elapsedTime) + ' seconds' + '\n')
# end function
def squareNum(num: float) -> float:
time.sleep(1.0)
return math.pow(num, 2)
# end function
if __name__ == '__main__':
main()
該腳本聲明 10 個浮點數,對它們進行平方(在每個平方上休眠 1 秒以模擬一些重要過程),然后將結果收集到一個新列表中。 運行大約需要 10 秒。
這是使用Multiprocessing
Process
和Queue
的重構版本:
from multiprocessing import Process, Queue
import time
import math
from typing import List
import pprint
def main():
print('\n' + 'starting . . .' + '\n')
startTime = time.time()
my_list = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
result_list = []
multiProcQueue = Queue()
processes: List[Process] = []
for num in my_list:
processes.append(Process(target=squareNum, args=(num, multiProcQueue,)))
# end for
for process in processes:
process.start()
# end for
for process in processes:
process.join()
# end for
while not multiProcQueue.empty():
result_list.append(multiProcQueue.get())
# end for
elapsedTime = time.time() - startTime
print('result_list: ')
pprint.pprint(result_list)
print('\n' + 'program took ' + '{:.2f}'.format(elapsedTime) + ' seconds' + '\n')
# end function
def squareNum(num: float, multiProcQueue: Queue) -> None:
time.sleep(1.0)
result = math.pow(num, 2)
multiProcQueue.put(result)
# end function
if __name__ == '__main__':
main()
該腳本運行大約 1 秒。 據我所知,這是讓多個進程將結果並行寫入同一數據結構的最干凈的方法。 我希望文檔https://docs.python.org/3/library/multiprocessing.html有這樣的示例。
請注意,結果列表的順序通常與輸入列表的順序不匹配,如果必須保持順序,則需要采用不同的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.