python apply_async不调用方法

时间:2016-12-29 12:09:13

标签: python-3.x multiprocessing

我有一个方法需要通过大型数据库进行处理,这需要花费数小时/天才能完成 参数存储在(长)列表中,其中max X应该在一个批处理中处理。该方法不需要返回任何内容,但我返回" True"为了"有趣" ...

当我线性地迭代它(在其他表中没有看到结果时生成/附加结果)时,该功能正常工作,但我无法得到apply_async或map_async工作。 (之前在其他项目中有效) 如果提前感谢,我将不胜感激任何可能出错的提示! 请参阅以下代码:

    import multiprocessing as mp

    class mainClass:
        #loads of stuff

    def main():
        multiprocess = True
        batchSize = 35

        mC = mainClass()
        while True:
            toCheck = [key for key, value in mC.lCheckSet.items()] #the tasks are stored in a dictionary, I'm referring to them with their keys, which I turn to a list here for iteration.
            if multiprocess == False:
                #this version works perfectly fine
                for i in toCheck[:batchSize]:
                    mC.check(i)
            else:
                #the async version does not, either with apply_async...
                with mp.Pool(processes = 8) as pool:
                    temp = [pool.apply_async(mC.check, args=(toCheck[n],)) for n in range(len(toCheck[:batchSize]))]
                    results = [t.get() for t in temp]

                #...or as map_async
                pool = mp.Pool(processes = 8)
                temp = pool.map_async(mC.check, toCheck[:batchSize])
                pool.close()
                pool.join()

    if __name__=="__main__":
        main()

2 个答案:

答案 0 :(得分:1)

这里的“气味”是你在主进程上实例化你的maincClass,只是一次,然后尝试在不同进程上调用一个方法 - 但请注意,当你将mC.check传递给你时进程池,它是一个已绑定到此进程中实例化的类的方法。

我猜你的问题出在哪里。虽然这可能有用 - 而且确实如此 - 我制作了这个简化版本并按预期工作:

import multiprocessing as mp
import random, time

class MainClass:
    def __init__(self):
        self.value = 1
    def check(self, arg):
        time.sleep(random.uniform(0.01, 0.3))
        print(id(self),self.value,  arg)

def main():
    mc = MainClass()

    with mp.Pool(processes = 4) as pool:
        temp = [pool.apply_async(mc.check, (i,)) for i in range(8)]
        results = [t.get() for t in temp]

main()

(您是否尝试过添加一些print以确保该方法根本不运行?) 因此,问题可能在于您的MainClass中的某些复杂状态,这种状态无法以良好的方式进入并行流程。可能的解决方法是在每个进程中实例化您的主类 - 这可以很容易地完成,因为MultiProcessing允许您获取current_process,并使用此对象作为命名空间来保持在工作池中实例化的进程中的数据,通过不同的调用来应用异步。

因此,创建一个新的check函数,如下所示 - 而不是在mainprocess中实例化mainclass,在池中的每个进程内实例化它:

import multiprocessing as mp
import random, time

def check(arg):
    process = mp.current_process
    if not hasattr(process, "main_class"):
        process.main_class = MainClass()
    process.main_class.check(arg)


class MainClass:
    def __init__(self):
        self.value = random.randrange(100)
    def check(self, arg):
        time.sleep(random.uniform(0.01, 0.3))
        print(id(self),self.value,  arg)

def main():
    mc = MainClass()

    with mp.Pool(processes = 2) as pool:
        temp = [pool.apply_async(check, (i,)) for i in range(8)]
        results = [t.get() for t in temp]

main()

答案 1 :(得分:0)

我遇到了同样的问题,我的apply_async调用根本没有被调用,但是我的情况是因为apply_async调用中的参数编号与函数声明中的编号不同