簡體   English   中英

使用Python實現單個使用者,多個生產者方案的最佳方法是什么?

[英]What's the best way to implement a single consumer, multiple producer scenario using Python?

我有一個Python程序,該程序產生多個生產者線程,然后有一個循環,等待Queue對象中包含某些東西。 看起來像這樣

for t in threads:
    t.start()
while len(threads):
    if not queue.empty():
        response = queue.get()
        # handle response
        queue.task_done()
    else:
        sleep(1)
    threads = [t for t in threads if t.is_alive()]

必須有一種更優雅的方法來執行此操作。 我已經研究了threading模塊提供的所有同步對象,但是看不到如何應用它們。

僅供參考,我擁有的代碼適用於我要執行的操作。 我堅信不要修復未損壞的東西,但是我只是覺得有一種更好的方法可以做到,一個更好的程序員本來可以做到的。

您可以使用weakref來測試線程是否仍然存在:

import weakref

def consumer(queue, threads):
    while threads:
        try:
            response = queue.get(timeout=1)
            # handle response
            queue.task_done()
        except Empty:
            pass

threads = weakref.WeakSet()
for i in range(10):
    t = threading.Thread(...)
    t.start()
    threads.add(t)
del t  # remove all references to threads

consumer(queue, threads)

// @丹尼爾:weakref是一個很酷的把戲。 這是一種替代方法,僅使用帶有添加的“終止策略”的隊列。

您將需要確保每個生產者的線程目標函數始終將最終的“終止消息”放入隊列,實質上在它們完成生產后為“無”。 使用者只是等待直到接收到適當數量的終止(每個生產者線程1個),然后退出循環。 這樣,您不必檢查線程是否已結束,並且實際上只有一個通信點:隊列。 但是,如果使用者中存在異常,則生產者線程可能應處於“守護程序”模式,以使它們在等待使用者隊列被良好使用時不會阻止進程。

您必須確保以某種嘗試最終縮進的方式始終向每個生產者發送終止消息。 否則,您將不得不在使用者的“ Empty”除外中處理超時。

import functools
def consumer(queue,num_threads_remaining):
    next_message=functools.partial(iter,functools.partial(queue.get,timeout=1),None)
    while num_threads_remaining:
        try:
            for response in next_message():
                # handle response.. hopefully exception-protected
                queue.task_done()
            # we got a None termination message
            num_threads_remaining -= 1
        except Empty: pass # handle some other check when idling?

暫無
暫無

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

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