簡體   English   中英

python multiprocessing共享隊列重新排序

[英]python multiprocessing shared queue re-ordering

我有一台服務器和幾個客戶端。 它們都共享一個任務,並且結果為multiprocessing.Queue。 但是,每當客戶端完成一項任務並將結果放入結果隊列時,我都希望服務器查看結果,然后基於此結果對任務隊列重新排序。

這當然意味着將所有內容從任務隊列中彈出並重新添加。 在此重新排序過程中,我希望客戶端阻止接觸任務隊列。 我的問題是我如何讓服務器識別何時將任務添加到結果隊列中,並通過鎖定任務隊列並在保護隊列的同時重新排序來做出反應。 不變的是,服務器必須在返回每個結果之后重新排序,然后客戶端才能獲得新任務。

我想一個簡單的(但是錯誤的)方法是讓multiprocessing.Value充當布爾值,並且每當添加結果時,客戶端就會將其翻轉為True,這意味着已經添加了結果。 服務器可以輪詢以獲得該值,但最終它可能會錯過輪詢之間添加另一個結果的另一個客戶端。

任何想法表示贊賞。

**'multithreading'標簽只是因為它與線程中的思想非常相似,我認為這里的進程/線程區別並不重要。

讓我們嘗試一些代碼-有些進步總比沒有好;-)問題的一部分是確保如果結果隊列中有內容,那么什么也不會從任務隊列中獲取,對吧? 因此,隊列緊密相連。 此方法將兩個隊列置於鎖的保護之下,並使用“條件”來避免進行輪詢的任何需要:

設置,在服務器中完成。 必須將taskQresultQtaskCondresultCond傳遞給客戶端進程(不需要顯式傳遞lock -它包含在條件中):

import multiprocessing as mp
taskQ = mp.Queue()
resultQ = mp.Queue()
lock = mp.Lock()
# both conditions share lock
taskCond = mp.Condition(lock)
resultCond = mp.Condition(lock)

客戶得到任務; 所有客戶端都使用此功能。 請注意,只要結果隊列中包含某些內容,就不會使用該任務:

def get_task():
    taskCond.acquire()
    while taskQ.qsize() == 0 or resultQ.qsize():
        taskCond.wait()
    # resultQ is empty and taskQ has something
    task = taskQ.get()
    taskCond.release()
    return task

客戶有結果:

with resultCond:
    resultQ.put(result)
    # only the server waits on resultCond
    resultCond.notify()

服務器循環:

resultCond.acquire()
while True:
    while resultQ.qsize() == 0:
        resultCond.wait()
    # operations on both queues in all clients are blocked now
    # ... drain resultQ, reorder taskQ ...
    taskCond.notify_all()

筆記:

  1. qsize()通常是概率性的,但是由於所有隊列操作都是在持有鎖的同時完成的,因此在這種情況下它是可靠的。

  2. 實際上,由於所有隊列操作均受此處自己的鎖保護,因此實際上無需使用mp.Queue 例如, mp.Manager().list()也可以工作(任何共享結構)。 也許當您重新安排任務時,列表會更容易使用?

  3. 我不喜歡的一部分:當服務器執行taskCond.notify_all() ,某些客戶端可能正在等待獲取新任務,而另一些客戶端可能正在等待返回新結果。 它們可以以任何順序運行。 任何等待返回結果的客戶端都有機會,所有等待獲取任務的客戶端都會阻塞,但是在此之前,任務將被消耗。 當然,這里的“問題”是我們不知道有什么新結果要等到實際添加到結果隊列中。

對於最后一個,也許將“客戶有結果”代碼更改為:

resultQ.put(result)
with resultCond:
    resultCond.notify()

會更好。 不確定。 這確實使推理變得非常困難,因為所有隊列操作都是在鎖的保護下完成的,這不再是事實。

暫無
暫無

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

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