我写了几个While True worker从队列中获取数据的例子。原则上,生产者应该表现得像下面这样,但实际上它是来自多个ssl套接字源的数据,因此这里的生产者是出于模拟目的。
毫秒级的分数在我的情况下非常重要,我正在努力确定如何确定以下哪种(或其他替代方案)最佳。我知道时间切片会影响响应能力。当我尝试运行下面的代码时,所有示例都适用于CPU负载,除了替代5,它占用了我100%的CPU。
到目前为止,我的结论是阻塞.get()比非阻塞.get()吃的CPU%少,因为非阻塞.get()循环设置得非常短,睡眠很短。
我的目标是实现能够占用CPU时间以及响应新更新的代码。也就是说,我希望其中一名工人在新项目到达队列之后的0.1毫秒内完成工作。
使用Python 2.7 for Windows 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)
答案 0 :(得分:0)
通过删除任何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
后,您还需要修改打印机。