Python: pass an argument in apply_async by reference

577 views Asked by At

In the code below I am trying to acsess the dictionaries in the list S:

import multiprocessing
from multiprocessing import Pool, cpu_count

def test(s):
    s["key"]+=1
    print( s )

S = [ { "key": 0 } for i in range(2) ]
pool = Pool(processes = 2 )
tasks = [ pool.apply_async( test, args = ( S[i], ) ) for i in range(2) ]

for t in tasks:
    t.get()
    
print(S)

As usually it happens in python I expect S[i] to be passed by reference. But what I get as output is: [{'key': 0}, {'key': 0}] instead of [{'key': 1}, {'key': 1}]. Why is it so? How can I acsess the elements in the dictionaries in parallel?

1

There are 1 answers

0
Александр Каренин On

The answer turned to be quite simple. This was already asked in Python multiprocessing: object passed by value?, but I found it too late. The right code is something like:

import multiprocessing
from multiprocessing import Pool, Manager, cpu_count


def test(s, d):
    print(s)
    s["key"]+=d
    print( s )
    return 0

S = [ { "key": 0 } for i in range(2) ]
d = 2
m = Manager()
my_shared_list = m.list(S)
pool = Pool(processes = 2 )
tasks = [ pool.apply_async( test, args = ( my_shared_list[i], d ) ) for i in range(2) ]

for t in tasks:
    t.get()