python多处理队列实现

时间:2018-01-21 02:54:57

标签: python queue multiprocessing

我无法理解如何将队列实现到下面的多处理示例中。基本上,我希望代码:

1)产生2个过程(完成)

2)将我的id_list分成两部分(完成)

3)让每个进程遍历列表打印出每个项目,并且仅在完成列表时关闭。我知道我必须实现某种类型的排队系统,并将其传递给每个工作者,但我不知道该怎么做。任何帮助将不胜感激。

from multiprocessing import Pool,Queue
id_list = [1,2,3,4,5,6,7,8,9,10]

def mp_worker(record):
    try:  
        print record
        sleep(1)
    except: pass
    print "worker closed"

def mp_handler():
    p = Pool(processes = 2) #number of processes
    p.map(mp_worker, id_list)  #devides id_list between 2 processes, defined above
    p.close()
    p.join()

mp_handler()

注意 - 代码打印出“工人关闭”10次。我喜欢这个陈述只打印两次(每个工人一次,每个工人打印出来自id_list的5个数字)

3 个答案:

答案 0 :(得分:3)

这对我有用(在Python 3上)。我没有使用Pool,而是生成了我自己的两个进程:

self.parent.get_screen('INSERTSCREENNAMEHERE').main_run()

虽然要处理的元素的长度是硬编码的。但它可能是mp_worker方法的第二个输入参数。

答案 1 :(得分:0)

你在那里的print语句会误导你 - 工作进程不会在函数结束时终止。实际上,工作进程在池关闭之前一直处于活动状态。此外,multiprocessing已经负责将列表拆分为块并为您排队每个任务。

至于你的另一个问题,如果你想在整个列表完成时触发异步事件,通常会将回调传递给map_async。每个块调用一次会对内部进行一些调整,但是如果你真的想要你可以:

def mapstar_custom(args):
    result = list(map(*args))
    print "Task completed"
    return result
...

pool._map_async(f, x, mapstar_custom, None, None, None).get()

编辑:我们似乎在混淆术语。当我说工人时我指的是池产生的过程,而你似乎意味着Selenium从这些过程产生的过程(这不在你的问题中)。只打开一次webdriver就很容易了:如果你有pool.map(module.task, ...),那么只需module.py

# ... selenium init here ...

def task(...):
    # ... use webdriver ...

模块只会由池工作人员导入一次,无论您派遣该任务多少次。所以顶级init只会发生一次。

答案 2 :(得分:0)

使用“池和队列”解决此问题的一种方法是


    from time import sleep
    from multiprocessing import Pool,Queue
    id_list = [1,2,3,4,5,6,7,8,9,10]

    def mp_worker(q):
        try:  
            print(q.get())
            sleep(.1)
        except: pass
        print ("worker closed")

    if __name__ == "__main__":
        q = Queue()
        p = Pool(processes = 2) #number of processes
        for x in id_list:
            q.put(x)
        p.map(mp_worker, id_list)  #devides id_list between 2 processes, defined above


您必须在代码的主要部分中按 put 将vaule添加到Quene中,并在函数中通过 get

从Queue中读取值