Python多处理 - 只是没有得到它

squ*_*808 6 python pool multiprocessing python-2.7 python-3.x

我花了一些时间试图理解多处理,虽然它的细节避开了我未经训练的头脑.我已经能够得到一个池来返回一个简单的整数,但如果该函数不仅仅返回一个结果,就像我可以找到的所有例子一样(即使在文档中,这是一个不起眼的例子,我也不太明白.

这是一个我正在努力工作的例子.但是,我不能按预期工作,我确信这有一个简单的原因.我可能需要使用队列或共享内存或管理器,但是当我阅读文档时,我似乎无法将我的大脑包围在它实际意味着什么以及它做什么.到目前为止,我所能了解的是泳池功能.

另外,我正在使用一个类,因为我需要避免使用全局变量,就像在这个问题的答案中一样.

import random

class thisClass:
    def __init__(self):
        self.i = 0

def countSixes(myClassObject):
    newNum = random.randrange(0,10)
    #print(newNum) #this proves the function is being run if enabled
    if newNum == 6:
        myClassObject.i += 1

if __name__ == '__main__':
    import multiprocessing
    pool = multiprocessing.Pool(1) #use one core for now

    counter = thisClass()

    myList = []
    [myList.append(x) for x in range(1000)]

    #it must be (args,) instead of just i, apparently
    async_results = [pool.apply_async(countSixes, (counter,)) for i in myList]

    for x in async_results:
        x.get(timeout=1)

    print(counter.i)
Run Code Online (Sandbox Code Playgroud)

有人可以愚蠢地解释需要做什么,这样我才能最终理解我所缺少的东西以及它的作用?

sen*_*rle 12

我花了一段时间才明白你想要发生什么.问题与多处理的工作方式有关.基本上,您需要以功能样式编写程序,而不是像现在一样依赖副作用.

现在,您正在向池中发送要修改的对象并且不返回任何内容countSixes.这不会与多工作,因为为了回避GIL,多创建一个副本counter,并将其发送到一个全新的解释.所以,当你增加i,实际上是增加一个副本i,然后,因为你回来没有,你放弃吧!

要做一些有用的事情,你必须从中返回一些东西countSixes.这是代码的简化版本,它可以执行与您想要的类似的操作.我留下了一个参数,只是为了表明你应该做什么,但实际上这可以通过零参数函数完成.

import random

def countSixes(start):
    newNum = random.randrange(0,10)
    if newNum == 6:
        return start + 1
    else:
        return start

if __name__ == '__main__':
    import multiprocessing
    pool = multiprocessing.Pool(1) #use one core for now

    start = 0
    async_results = [pool.apply_async(countSixes, (start,)) for i in range(1000)]

    print(sum(r.get() for r in async_results))
Run Code Online (Sandbox Code Playgroud)

  • 你先生是绅士和学者.我能够使用它来重新设计我的程序以返回一个类实例(这也是我需要类的原因)现在事情正在发挥作用!没有你的解释,我不可能做到!*舞蹈* (5认同)