简体   繁体   English

如何在 Python 3.8 的多处理中共享字符串数组?

[英]How to share an Array of strings in multiprocessing in Python 3.8?

I am experimenting with Python's (v. 3.8) multiprocessing library, for developing a bigger program, and trying to share an multiprocessing.Array of strings between multiple processes such that this Array can be updated and read by each process with the same data.我正在试验 Python (v. 3.8) multiprocessing 库,用于开发更大的程序,并尝试在多个进程之间共享multiprocessing.Array字符串,以便每个进程可以使用相同的数据更新和读取该Array I tried c_char_p and it says to use byte strings.我试过c_char_p ,它说使用byte字符串。 However, for this code:但是,对于此代码:

from multiprocessing import Process, Array
from ctypes import c_char_p

def show(a):
    print("This ran")
    print("a: ", a[:])

if __name__ == "__main__":
    array = Array(c_char_p, 1)
    array[0] = b'Hello World'
    print(array[:])
    p = Process(target=show, args=(array,))
    p.start()
    p.join()

the output varies from this:输出与此不同:

[b'Hello World']
This ran
a:  [b'c']

to this:对此:

[b'Hello World']
This ran

but I expect:但我希望:

['Hello World']
This ran
['Hello World']

I guess an obvious solution would be to share a common file between each process but I expect to use multiple arrays and that can get a bit tedious.我想一个明显的解决方案是在每个进程之间共享一个公共文件,但我希望使用多个数组,这可能会有点乏味。 I was wondering what be the best current solution to this in Python 3.8.我想知道 Python 3.8 中目前最好的解决方案是什么。

For this code:对于此代码:

from multiprocessing import Process, Array
from ctypes import c_char_p

def show(a):
    print("This ran")

    # Decode the encoded values
    arr = [s.decode("utf-8") for s in a]
    print(arr)

if __name__ == "__main__":
    array = Array(c_char_p, 1)
    message = b"Hello, world"
    array[0] = message

    p = Process(target=show, args=(array,))
    p.start()
    p.join()

    # Decode the encoded values
    arr = [s.decode("utf-8") for s in array]
    print(arr)

it never ends (ie never gets to the print statement after the process starts), the output is:它永远不会结束(即在进程开始后永远不会到达打印语句),输出是:

This ran

I am not sure why.我不知道为什么。

The values are stored in array as the encoded strings(byte values) , so when you want the string values you have to decode them.这些值作为编码字符串(字节值)存储在array中,因此当您需要字符串值时,您必须对其进行解码

Try this:尝试这个:

from multiprocessing import Process, Array
from ctypes import c_char_p

def show(a):
    print("This ran")

    # Decode the encoded values
    arr = [s.decode("utf-8") for s in a]
    print(arr)

if __name__ == "__main__":
    array = Array(c_char_p, 1)
    array[0] = b"Hello, world"

    # Decode the encoded values
    arr = [s.decode("utf-8") for s in array]
    print(arr)

    p = Process(target=show, args=(array,))
    p.start()
    p.join()

Output:输出:

['Hello, world']
This ran
['Hello, world']

I don't think it is supposed to work in general.我不认为它应该在一般情况下工作。

Basically, c_char_p is a pointer, a number that references a memory location in a process.基本上, c_char_p是一个指针,一个引用进程中内存位置的数字。 And you cannot expect pointers to be portable between processes.并且您不能期望指针在进程之间是可移植的。

Since Python Process -es inherit from their parent processes it might work for strings that were created before the child process was started.由于 Python Process -es 从其父进程继承,它可能适用于在子进程启动之前创建的字符串。

But you cannot expect to create a new string in the child process, add a pointer to the Array and expect it to be valid in the parent process.但是您不能期望在子进程中创建一个新字符串,添加一个指向 Array 的指针并期望它在父进程中有效。 (Nor the other way around.) (反之亦然。)

Using a Pipe or a Queue is probably a better way to exchange string data.使用PipeQueue可能是交换字符串数据的更好方法。

Edit 1:编辑1:

Use a Pipe to send mutations of a list of strings, eg as a tuple (3, "new value") .使用Pipe发送字符串列表的突变,例如作为元组(3, "new value") This would mean that the item 3 in the list now becomes "new value" .这意味着列表中的第 3 项现在变成了"new value" Using a duplex Pipe means that both ends of the pipe can read and apply every message that comes in.使用双工Pipe意味着Pipe两端都可以读取和应用传入的每条消息。

Edit 2 :编辑2

Another option would be to use amultiprocessing.Manager .另一种选择是使用multiprocessing.Manager This will allow you to share list s and dict s.这将允许您共享listdict

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM