How to use multiprocessing pool.map with multiple arguments?

前端 未结 20 3472
-上瘾入骨i
-上瘾入骨i 2020-11-21 11:24

In the Python multiprocessing library, is there a variant of pool.map which supports multiple arguments?

text = "test"
def         


        
相关标签:
20条回答
  • 2020-11-21 12:04

    is there a variant of pool.map which support multiple arguments?

    Python 3.3 includes pool.starmap() method:

    #!/usr/bin/env python3
    from functools import partial
    from itertools import repeat
    from multiprocessing import Pool, freeze_support
    
    def func(a, b):
        return a + b
    
    def main():
        a_args = [1,2,3]
        second_arg = 1
        with Pool() as pool:
            L = pool.starmap(func, [(1, 1), (2, 1), (3, 1)])
            M = pool.starmap(func, zip(a_args, repeat(second_arg)))
            N = pool.map(partial(func, b=second_arg), a_args)
            assert L == M == N
    
    if __name__=="__main__":
        freeze_support()
        main()
    

    For older versions:

    #!/usr/bin/env python2
    import itertools
    from multiprocessing import Pool, freeze_support
    
    def func(a, b):
        print a, b
    
    def func_star(a_b):
        """Convert `f([1,2])` to `f(1,2)` call."""
        return func(*a_b)
    
    def main():
        pool = Pool()
        a_args = [1,2,3]
        second_arg = 1
        pool.map(func_star, itertools.izip(a_args, itertools.repeat(second_arg)))
    
    if __name__=="__main__":
        freeze_support()
        main()
    

    Output

    1 1
    2 1
    3 1
    

    Notice how itertools.izip() and itertools.repeat() are used here.

    Due to the bug mentioned by @unutbu you can't use functools.partial() or similar capabilities on Python 2.6, so the simple wrapper function func_star() should be defined explicitly. See also the workaround suggested by uptimebox.

    0 讨论(0)
  • 2020-11-21 12:06

    There are many answers here, but none seem to provide Python 2/3 compatible code that will work on any version. If you want your code to just work, this will work for either Python version:

    # For python 2/3 compatibility, define pool context manager
    # to support the 'with' statement in Python 2
    if sys.version_info[0] == 2:
        from contextlib import contextmanager
        @contextmanager
        def multiprocessing_context(*args, **kwargs):
            pool = multiprocessing.Pool(*args, **kwargs)
            yield pool
            pool.terminate()
    else:
        multiprocessing_context = multiprocessing.Pool
    

    After that, you can use multiprocessing the regular Python 3 way, however you like. For example:

    def _function_to_run_for_each(x):
           return x.lower()
    with multiprocessing_context(processes=3) as pool:
        results = pool.map(_function_to_run_for_each, ['Bob', 'Sue', 'Tim'])    print(results)
    

    will work in Python 2 or Python 3.

    0 讨论(0)
提交回复
热议问题