Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to initialize a string array for multiprocessing

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'
[]
like image 950
SagwaTheCat Avatar asked Sep 06 '15 02:09

SagwaTheCat


1 Answers

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.

like image 185
Padraic Cunningham Avatar answered Oct 31 '22 09:10

Padraic Cunningham