I’m testing some code using multiprocessing to try to understand it, but I’m struggling to get the .Value to work. What am I doing wrong, it says p doesn’t exist?
here’s my code:
from multiprocessing import Pool, Value from ctypes import c_int if __name__ =="__main__": p=Value(c_int,1) def addone(a): print(a) with p.get_lock(): print(p.value) p.value += 1 if __name__ =="__main__": with Pool() as po: po.map(addone,range(19)) print(p.value)
And I get this error:
multiprocessing.pool.RemoteTraceback: """ Traceback (most recent call last): File "C:Users(I removed this)AppDataLocalProgramsPythonPython39libmultiprocessingpool.py", line 125, in worker result = (True, func(*args, **kwds)) File "C:Users(I removed this)AppDataLocalProgramsPythonPython39libmultiprocessingpool.py", line 48, in mapstar return list(map(*args)) File "C:Users(I removed this)DesktopPythonmakemultiTest.py", line 10, in addone with p.get_lock(): NameError: name 'p' is not defined """ The above exception was the direct cause of the following exception: Traceback (most recent call last): File (I removed this), line 15, in <module> po.map(addone,range(19)) File "C:Users(I removed this)AppDataLocalProgramsPythonPython39libmultiprocessingpool.py", line 364, in map return self._map_async(func, iterable, mapstar, chunksize).get() File "C:Users(I removed this)AppDataLocalProgramsPythonPython39libmultiprocessingpool.py", line 771, in get raise self._value NameError: name 'p' is not defined
What should I do?
Advertisement
Answer
You only want a single instance of the shared value, p
, to be operated on by the pool processes executing your worker function, addone
. The way to do this is to use the initalizer and initargs arguments of the multiprocessing.pool.Pool
class to initialize a global variable, p
, in each pool process with the shared value created by the main process. Passing explicitly p
to a multiprocessing pool worker function as an additional argument will not work; this will result in the cryptic error: RuntimeError: Synchronized objects should only be shared between processes through inheritance.
def init_pool_processes(shared_value): global p p = shared_value def addone(a): print(a) with p.get_lock(): print(p.value) p.value += 1 if __name__ =="__main__": from multiprocessing import Pool, Value from ctypes import c_int p = Value(c_int, 1) with Pool(initializer=init_pool_processes, initargs=(p,)) as po: po.map(addone, range(19)) print(p.value)