Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python (multiprocessing): How to pass a dictionary as the argument of a worker process initializer function?

I'm using a function to initialize the worker processes of a process pool, and this function has a single argument, which is a dictionary. When the process pool is created and the function is called to initialize each worker process I get an error regarding the wrong number of arguments:

TypeError: _init_worker() takes 1 positional argument but 2 were given

The process initializer function being used:

def _init_worker(shared_arrays):

    _global_shared_arrays = shared_arrays

The initializer is being called in the normal way for each worker process:

with multiprocessing.Pool(processes=_NUMBER_OF_WORKER_PROCESSES,
                          initializer=_init_worker, initargs=(arrays_dict)) as pool:

I think this has something to do with how dictionaries are passed as the argument, in that the above error always lists the number of items in the dictionary as the number of positional arguments that were passed, as if what's being passed is the keys of the dictionary rather than the dictionary itself. When I step into the code in the debugger this is exactly what's going on, i.e. if there's a single item in the dictionary argument then only the key is passed through to the initializer function, rather than the dictionary itself.

If there are multiple items in the dictionary used as the argument being passed to the initializer function then the above error message is displayed, reporting the number of items in the dictionary as the number of positional arguments given, so it's somehow passing the keys of the dictionary as arguments rather than the dictionary itself.

What am I doing wrong here?

like image 958
James Adams Avatar asked Dec 18 '25 17:12

James Adams


2 Answers

initargs will be unpacked, so you must pass a tuple, like

initargs=(arrays_dict,)
like image 168
pxe Avatar answered Dec 20 '25 09:12

pxe


if you look at the documentation here

you will see the following:

If initializer is not None then each worker process will   
call initializer(*initargs) when it starts.  

as you can see the the args for the initializer function are are being unpacked by the * operator.
So your custom init function should be ready to accept more than one argument in case you pass it a dict with more than one element or else it will fail.
Something like this: def _init_worker(*shared_arrays)

like image 39
eladm26 Avatar answered Dec 20 '25 08:12

eladm26



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!