python多处理池将对象分配给worker

时间:2016-05-11 14:01:21

标签: python

我需要处理一些对象。我想知道是否有办法根据唯一键将工作(流程)分配给对象 第一次当代码看到对象时,它应该被随机分配一个worker,但是如果该对象再次出现,它应该被分配给之前处理该对象的worker。谢谢你

例如:
工人A,B,C |第一束物体1,2,3,4第二束物体1,3
第一批对象:
工人A< --- 1,3
工人B< --- 2
工人C< --- 4
第二束物体:
工人A< --- 1,3
工人B< ---
工人C< ---

1 个答案:

答案 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()返回结果)留作练习。