6

Here is sample code of Sharing state between processes

from multiprocessing import Process, Value, Array

def f(n, a):
    n.value = 3.1415927
    for i in range(len(a)):
        a[i] = -a[i]

if __name__ == '__main__':
    num = Value('d', 0.0)
    arr = Array('i', range(10))

    p = Process(target=f, args=(num, arr))
    p.start()
    p.join()

    print(num.value)
    print(arr[:])

The output is

3.1415927
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]

I want to initialize a list with string elements instead of integer elements. Then I want to assign the list specific string elements. My code is the following.

from multiprocessing import Process, Value, Array

def f(a):
    a = ["up", "down", "left"]

if __name__ == '__main__':
    arr = Array('b', [])

    p = Process(target=f, args=(arr))
    p.start()
    p.join()

    print(arr[:])

I want the output to be

["up", "down", "left"]

But instead I get the output

TypeError: f() missing 1 required positional argument: 'a'
[]
1
  • I fixed the Type Error, but the main part of my question is still unanswered. I still receive an empty list as my output. Commented Sep 6, 2015 at 2:21

2 Answers 2

6

You need to pass a tuple of args, you need to add a trailing comma to create a tuple:

 p = Process(target=f, args=(arr,)) # <- trailing comma

Or use tuple explicitly:

 args=tuple([arr]))

The comma creates the tuple not the parens.

No idea how multiprocessing will help but to get the output you want:

from multiprocessing import Process, Value, Array
from ctypes import c_char_p
def f(a):
    a[:] = ["up", "down", "left"]


if __name__ == '__main__':
    arr = Array(c_char_p, 3)
    p = Process(target=f, args=(arr,))
    p.start()
    p.join()
    print(arr[:])
['up', 'down', 'left']

The first arg to Array is the type which we need to use ctypes.c_char_p as we are adding strings, the second arg is the size of the array i.e 3 elements.

Sign up to request clarification or add additional context in comments.

14 Comments

Thanks, I fixed the tuple error, but I am still not getting my desired output. I still receive the empty list [ ]. Do you know how to fix this?
@SagwaTheCat, that is completely different to your original question but obviously you get an empty list as your function does nothing and arr is an empty array so you get an empty array, what else would you expect?
Thanks for that, but I am getting the following output now TypeError: bytes or integer address expected instead of str instance [None, None, None]
Ah ok, just saw you are using python3, to work as is you would need to pass bytes [b"up", b"down", b"left"], an explanation is here stackoverflow.com/questions/7237133/…, are you actually using strings?
That's odd, probably something wrong with my code. I'll try to fix this. Thanks for all your help.
|
3

Process expects args to be a tuple, instead you just pass arr.

https://docs.python.org/2/library/multiprocessing.html

args is the argument tuple for the target invocation.

a = (arr)
print(type(a))
# Output: <class 'multiprocessing.sharedctypes.SynchronizedArray'>

a = (arr,)
print(type(a))
# Output: <type 'tuple'>

This fixes your problem:

p = Process(target=f, args=(arr,))  # notice the , after arr

1 Comment

Pretty the same, but obviously we wrote the answer simultaneously? We answered almost at the same time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.