下面的代码首先启动多个进程。然后,它运行一个--zabbix-template
循环,检查while True
对象。最后,它迭代过程以检查是否还活着。完成所有过程后,将进行queue
breaks
循环。
不幸的是,它发生在while
对象不为空的情况下。在没有获取数据存储在queue
中的情况下中断循环可能很容易导致数据丢失。如何修改代码逻辑,以确保在中断循环之前queue
对象为空?
queue
答案 0 :(得分:2)
再次出现同步问题。当您检查队列发现它为空时,不能保证将来不会有新项目出现。
您可以在子进程完成其工作时将标记放置在队列中,以通知队列中将没有更多项目。父进程可能会耗尽队列,直到得到前哨。这也是multiprocessing.Pool
使用的方法。您可以在此处使用None
作为哨兵:
def foo(*args):
for i in range(3):
queue = args[0]
queue.put(os.getpid())
queue.put(None)
...
while items:
for proc in tuple(items.keys()):
queue = items[proc]
if not queue.empty():
r = queue.get()
print(r)
if r is None:
proc.join()
del items[proc]
time.sleep(0.1)
答案 1 :(得分:0)
一个有效的解决方案在下面发布。该方法不是使用Process.run
运行proc,而是使用multiprocessing.pool.ThreadPool.map_async
方法启动进程而不会阻塞。然后,multiprocessing.Queue
对象用于存储可由MainProcess运行的foo
函数访问的数据。
import time, multiprocessing, Queue
from multiprocessing.pool import ThreadPool
logger = multiprocessing.log_to_stderr()
def foo(args):
queue = args[0]
arg = args[1]
for i in range(3):
time.sleep(2)
queue.put([arg, time.time()])
pool = ThreadPool(processes=4)
queue = multiprocessing.Queue()
map_result = pool.map_async(foo, [(queue, arg) for arg in range(3)])
logger.warning("map_result: %s" % map_result)
map_result.wait(timeout = 10)
if not map_result.ready():
message = '%s is timed out and terminated.' % pool
log.error(message)
pool.terminate()
raise Exception(message)
while not queue.empty():
if queue.empty():
break
logger.warning("queue_data: %r" % queue.get(True, 0.1))
pool.close()
pool.join()
答案 2 :(得分:0)
#encoding:utf-8
from multiprocessing import Pool, Manager
def tiny(q, j):
if len(j) < 100:
q.put(j+j[-1])
print " Done!", j
q.put(-1)
return
queue = Manager().Queue()
pool = Pool(processes=10)
pool.apply_async(tiny, (queue, "A"))
pool.apply_async(tiny, (queue, "B"))
pool.apply_async(tiny, (queue, "C"))
created = 3
fininshed = 0
while created > fininshed:
i = queue.get(True, None)
if isinstance(i, int):
fininshed += 1
else:
created += 1
pool.apply_async(tiny, (queue, i))
pool.close()
pool.join()
print [worker.is_alive() for worker in pool._pool]