有没有办法在嵌套函数或模块中使用multiprocessing.pool?

时间:2018-03-01 00:01:12

标签: python python-2.7

谢谢你看看这个。我承认我已经在python中进行了1周的并行处理,所以如果我错过了一个明显的解决方案,我会道歉。我有一段代码,我想运行几个不同的mp.pool()实例。主要.py文件上的那些调用工作正常,但当我尝试将它们添加到模块中的函数时,我得不到它们的所有输出。该应用程序只是运行它并继续。我认为它可能与此post有关,但它没有提供任何关于完成我需要的替代方法的想法。在一个简单示例中工作的代码是:

import multiprocessing as mp
def multiproc_log_result(retval):
    results.append(retval)
    if len(results) % (10 // 10) == 0:
        print('{0}% done'.format(100 * len(results) / 10))

def meat():
    print 'beef'
    status = True
    return status
results = []
pool = mp.Pool(thread_count)
for x in range(10):
    pool.apply_async(meat, callback=multiproc_log_result)
pool.close()
pool.join()


def veggie():
    print 'carrot'
    status = True
    return status

results = []
pool = mp.Pool(thread_count)
for x in range(10):
    pool.apply_async(veggie, callback=multiproc_log_result)
pool.close()
pool.join()

不起作用的代码是:

import multiprocessing as mp
def multiproc_log_result(retval):
    results.append(retval)
    if len(results) % (10 // 10) == 0:
        print('{0}% done'.format(100 * len(results) / 10))

def meat():
    print 'beef'
    status = True
    return status
results = []
pool = mp.Pool(thread_count)
for x in range(10):
    pool.apply_async(meat, callback=multiproc_log_result)
pool.close()
pool.join()

def nested_stupid_fn():
    def multiproc_log_result(retval):
        results.append(retval)
        if len(results) % (10 // 10) == 0:
            print('{0}% done'.format(100 * len(results) / 10))

    def veggie():
        print 'carrot'
        status = True
        return status

    results = []
    pool = mp.Pool(thread_count)
    for x in range(10):
        pool.apply_async(veggie, callback=multiproc_log_result)
    pool.close()
    pool.join()
nested_stupid_fn()

最终,我希望通过将其置于单独模块中的另一个功能中而不再使用该示例的示例。因此,当我导入模块packngo并将其用作packngo.basic_packngo(输入)并在其中的某个位置具有嵌套函数的内容时,它们将运行。任何帮助将不胜感激。 :D我是一个非常简单的人,所以如果你可以向孩子解释,那么它可能会沉入我的脑海!

2 个答案:

答案 0 :(得分:1)

您链接的另一个问题有解决方案,只是没有明确说明:您不能使用嵌套函数作为func / {{1}的apply*参数} *map*上的方法族。它们适用于multiprocessing.Pool,因为multiprocessing.dummy.Pool由可以直接传递函数引用的线程支持,但是multiprocessing.dummy必须使函数腌制,并且只有具有可导入名称的函数才能被腌制。如果您检查嵌套函数的名称,则类似于multiprocessing.Pool,并且modulename.outerfuncname.<locals>.innerfuncname组件将使其无法导入(这通常是一件好事;利用嵌套的嵌套函数通常具有范围内处于临界状态,仅导入会丢失)。

最好<locals>函数以嵌套方式定义,因为它们是在父进程中执行的,因此不会发送给工作人员。在您的情况下,只有回调依赖于闭包作用域,因此将callbackfunc)移到全局作用域,将veggie模块定义为: >

packngo

是的,这意味着def veggie(): print 'carrot' status = True return status def nested_stupid_fn(): def multiproc_log_result(retval): results.append(retval) if len(results) % (10 // 10) == 0: print('{0}% done'.format(100 * len(results) / 10)) results = [] pool = mp.Pool(thread_count) for x in range(10): pool.apply_async(veggie, callback=multiproc_log_result) pool.close() pool.join() nested_stupid_fn() 成为相关模块的公开成员。如果要表明它应被视为实现详细信息,则可以在其下加上下划线(veggie),但是必须与_veggie一起使用时,它必须是全局的。

答案 1 :(得分:0)

我认为问题是multiproc_log_result范围内的变量results不存在。 所以你应该做的是直接追加结果你的异步调用结果。 您将无法跟踪进度(无法直接在类之外共享回调函数的全局变量)

from multiprocessing.pool import ThreadPool

def nested_stupid_fn():
    def multiproc_log_result(retval):
        results.append(retval)

    def veggie():
        print 'carrot'
        status = True
        return status

    results = []
    pool = ThreadPool(thread_count)
    for x in range(10):
        results.append(pool.apply_async(veggie))

    pool.close()
    pool.join()

    results = [result.get() for result in results]  # get value from async result

    ...then do stuff with results