我需要处理一些对象。我想知道是否有办法根据唯一键将工作(流程)分配给对象 第一次当代码看到对象时,它应该被随机分配一个worker,但是如果该对象再次出现,它应该被分配给之前处理该对象的worker。谢谢你
例如:
工人A,B,C |第一束物体1,2,3,4第二束物体1,3
第一批对象:
工人A< --- 1,3
工人B< --- 2
工人C< --- 4
第二束物体:
工人A< --- 1,3
工人B< ---
工人C< ---
答案 0 :(得分:0)
实现“粘性会话”的一种非常简单的方法是制作您自己的multiprocessing.Pool
版本,该版本不会急切地分配工作项,而是确定性地分配它们。这是一个不完整但可运行的解决方案:
import multiprocessing
import os
import time
def work(job):
time.sleep(1)
print "I am process", os.getpid(), "processing job", job
class StickyPool:
def __init__(self, processes):
self._inqueues = [multiprocessing.Queue() for ii in range(processes)]
self._pool = [multiprocessing.Process(target=self._run, args=(self._inqueues[ii],)) for ii in range(processes)]
for process in self._pool:
process.start()
def map(self, fn, args):
for arg in args:
ii = hash(arg) % len(self._inqueues)
self._inqueues[ii].put((fn, arg))
def _run(self, queue):
while True:
fn, arg = queue.get()
fn(arg)
pool = StickyPool(3)
#pool = multiprocessing.Pool(3)
pool.map(work, [1,2,3,4,1,2,3,4,1,2,3,4])
time.sleep(4)
使用上述StickyPool
时,会根据参数的哈希值分配作业。这意味着每次都使用相同的参数进行相同的处理。如果有许多独特的值,其中的哈希值会发生冲突,那么均匀分配作业是不够智能的,但是哦 - 很好 - 未来改进的空间。我也没有打扰关闭逻辑,因此如果你使用StickyPool
,程序不会停止运行,但如果你使用multiprocessing.Pool
,它就会停止运行。修复这些问题并实施更多Pool
界面(例如apply()
,并从map()
返回结果)留作练习。