![](/img/trans.png)
[英]Python Multiprocessing queue.get() timeout when queue is not empty
[英]Multiprocessing: Responsiveness vs CPU load when using multiple while true queue.get() workers
我寫了一些While True工作程序示例,它們從隊列中獲取數據。 原則上,生產者的行為應類似於以下內容,但實際上,它是來自多個ssl套接字供稿的數據,因此此處的生產者用於模擬目的。
在我的情況下,毫秒的分數很重要,而且我在如何確定以下替代方法(或某些其他替代方法)中最好的方法上很掙扎。 我了解到時間分割可能會影響響應速度。 當我嘗試運行下面的代碼時,涉及CPU負載的所有示例均運行良好,除了替代5占用了我100%的CPU。
到目前為止,我的結論是,鑒於非阻塞式.get()循環的睡眠時間非常短,阻塞式.get()所消耗的CPU比非阻塞式.get()少。
我的目標是實現將占用很少的CPU時間並響應新更新的代碼。 即,我希望其中一名工人在新物品到達隊列后的0.1毫秒內完成工作。
適用於Windows 7的以Python 2.7編寫的示例代碼(請注意,我使用的是24核計算機,因此可能需要調低工作人員的數量):
import multiprocessing
import os
import time
import Queue
class MyClass:
def __init__(self):
self.the_queue = multiprocessing.Queue()
self.printerq = multiprocessing.Queue()
def producer(self):
i=0
while True:
self.the_queue.put(["hello",i],False)
i=i+1
time.sleep(1)
'alternative 1'
'''
def worker_main(self):
while True:
try:
item = self.the_queue.get(timeout=0.1)
except Queue.Empty:
time.sleep(0.0001)
else:
self.printerq.put([item,os.getpid()],False)
'''
'alternative 2'
'''
def worker_main(self):
while True:
if not self.the_queue.empty():
item = self.the_queue.get()
#print os.getpid(), "got", item
self.printerq.put([item,os.getpid()],False)
time.sleep(0.0001)
'''
'alternative 3'
def worker_main(self):
while True:
item = self.the_queue.get()
self.printerq.put([item,os.getpid()],False)
'alternative 4'
'''
def worker_main(self):
while True:
item = self.the_queue.get()
self.printerq.put([item,os.getpid()],False)
time.sleep(0.0001)
'''
'alternative 5 eats CPU 100%'
'''
def worker_main(self):
while True:
try:
item = self.the_queue.get(False)
except Queue.Empty:
time.sleep(0.0001)
else:
self.printerq.put([item,os.getpid()],False)
time.sleep(0.0001)
'''
def printer(self):
while True:
stuff=self.printerq.get()
print stuff
if __name__=='__main__':
mc=MyClass()
process_printer = multiprocessing.Process(target=mc.printer, args=())
process_printer.start()
for i in range(100):
process_window = multiprocessing.Process(target=mc.worker_main, args=())
process_window.start()
time.sleep(0.1)
for i in range(100):
process_producer = multiprocessing.Process(target=mc.producer, args=())
process_producer.start()
time.sleep(0.1)
您最有可能通過刪除任何time.sleep()
調用來獲得最佳性能。 我建議使用queue.get()
進行繁忙的等待,並使用kill標志結束進程。 您的工人應該看起來像這樣:
def worker_main(self):
while True:
item = self.the_queue.get()
# Checks for kill flag
if item == None:
break
self.printerq.put([item,os.getpid()],False)
此方法要求您的生產者將None
放入self.the_queue
。 但是,因為您有多個生產者,所以您可能需要修改這些工人,以便他們從每個生產者那里收到一個終止標志。 就像是:
def worker_main(self):
kill_flags = 0
# Make sure to pass in num_producers
while kill_flags < num_producers:
item = self.the_queue.get()
# Checks for kill flag
if item == None:
kill_flag += 1
continue
self.printerq.put([item,os.getpid()],False)
就您的生產者而言,當他們完成生產時,類似的方法也會起作用:
def producer(self):
i=0
while (some_condition_to_stop_producing):
self.the_queue.put(["hello",i],False)
i=i+1
time.sleep(1)
# Pass in the number of workers
for i in range(num_workers):
self.the_queue.put(None)
別忘了,在將東西放入printerq
還需要修改打印機以使其printerq
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.