Python多处理中的嵌套并行性

时间:2018-04-20 18:45:47

标签: python multiprocessing python-multiprocessing

我知道这听起来像是之前被问过的事情,但等等,我会解释为什么其他选项不起作用。

我目前正在使用multiprocessing.Pool在应用程序中实现并行性,并希望将其扩展为能够利用嵌套并行性。将Pool对象作为参数传递给apply_async的天真方法并不起作用as noted in other answers,因为Pool无法被腌制。

以下是我的要求:

  1. 我需要某种池来限制并发执行任务的数量。例如。 multiprocess.Pool用于此目的,但不能将其传递给其他流程。

  2. 我需要嵌套并行。在我的应用程序中,我需要执行I / O以识别嵌套工作是什么,所以我绝对不想从单个线程中执行此操作。我认为这排除了this question的所有答案。

  3. 它需要在标准库中;我无法添加依赖项。这排除了this answer

  4. 我真的很喜欢使用Python 2和3.但是,如果可以证明移动到Python 3可以解决我的问题,我会考虑它。

    < / LI>

    我不需要特别使用多个进程,使用线程是可以的,因为大部分工作都是I / O或等待子进程完成。

    我尝试使用multiprocessing.dummy,它是相同的界面,但在threading之上实现。但是,当我尝试调用get()来检索我的测试结果时,我收到以下错误,所以我认为这已经不存在了。

      File "/usr/lib/python2.7/multiprocessing/pool.py", line 567, in get
        raise self._value
    ValueError: signal only works in main thread
    

    我知道Python 3中的concurrent.futures库,但这似乎有一些严重的限制。例如,本节中的第二个例子在我的案例中似乎是一个显示阻止者:

    https://docs.python.org/3/library/concurrent.futures.html#threadpoolexecutor

    我不知道如何通过基本上任何直接编写的嵌套并行算法来避免这种情况。所以,即使我愿意使用Python 3,我认为这是一个非首发。

    在没有编写自己的实现的情况下,我不知道标准库中有任何其他可用选项。

1 个答案:

答案 0 :(得分:1)

你似乎已经排除了它,但我怀疑 如果您能够迁移到Python 3,或者为Python 2添加依赖项,https://docs.python.org/3/library/concurrent.futures.html#threadpoolexecutorhttps://docs.python.org/3/library/concurrent.futures.html#processpoolexecutor将起作用。

如果在处理该文件之前不必触发每个文件的额外工作,则可以使用单个协调线程触发所有其他文件,因此可以防止死锁,如下例所示。

Await.result(future, 365 days)

或者,如果第一级上的每个线程都需要自己触发工作,那么额外的工作可能需要在另一个池中以防止死锁(取决于每个未来调用import base64 with open(full_path, 'rb') as imgFile: image = base64.b64encode(imgFile) 的时间),如下所示。

from concurrent.futures import ThreadPoolExecutor
import time

pool = ThreadPoolExecutor(max_workers=3)

def find_work_inputs(dummy_file):
    print("{}: Finding work...".format(dummy_file))
    time.sleep(1)
    work = range(0, dummy_file)
    print("{}: Work is {}".format(dummy_file, work))
    return work

def do_work(dummy_file, work_input):
    print("{}: {}".format(dummy_file, work_input))
    print("{}: Doing work {}...".format(dummy_file, work_input))
    time.sleep(1)
    return work_input * work_input

dummy_files = [1,2,3,4,5]

futures = []
for dummy_file in dummy_files:
    work_inputs = pool.submit(find_work_inputs, dummy_file)
    for work_input in work_inputs.result():
        result = work_input
        futures.append((dummy_file, result, pool.submit(do_work, dummy_file, result)))

for dummy_file, work_input, future in futures:
    print("Result from file:{} input:{} is {}".format(dummy_file, work_input, future.result()))