This question already has an answer here:
I need some way to use a function within pool.map() that accepts more than one parameter. As per my understanding, the target function of pool.map() can only have one iterable as a parameter but is there a way that I can pass other parameters in as well? In this case, I need to pass in a few configuration variables, like my Lock() and logging information to the target function.
I have tried to do some research and I think that I may be able to use partial functions to get it to work? However I don't fully understand how these work. Any help would be greatly appreciated! Here is a simple example of what I want to do:
def target(items, lock):
for item in items:
# Do cool stuff
if (... some condition here ...):
lock.acquire()
# Write to stdout or logfile, etc.
lock.release()
def main():
iterable = [1, 2, 3, 4, 5]
pool = multiprocessing.Pool()
pool.map(target(PASS PARAMS HERE), iterable)
pool.close()
pool.join()
You can use
functools.partial
for this (as you suspected):Example:
Output:
You could use a map function that allows multiple arguments, as does the fork of
multiprocessing
found inpathos
.pathos
enables you to easily nest hierarchical parallel maps with multiple inputs, so we can extend our example to demonstrate that.Even more fun, is to build a nested function that we can pass into the Pool. This is possible because
pathos
usesdill
, which can serialize almost anything in python.If you are not able to go outside of the standard library, however, you will have to do this another way. Your best bet in that case is to use
multiprocessing.starmap
as seen here: Python multiprocessing pool.map for multiple arguments (noted by @Roberto in the comments on the OP's post)Get
pathos
here: https://github.com/uqfoundationIn case you don't have access to
functools.partial
, you could use a wrapper function for this, as well.This makes
target()
into a function that accepts a lock (or whatever parameters you want to give), and it will return a function that only takes in an iterable as input, but can still use all your other parameters. That's what is ultimately passed in topool.map()
, which then should execute with no problems.