繁体   English   中英

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

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

我正在试验 Python (v. 3.8) multiprocessing 库,用于开发更大的程序,并尝试在多个进程之间共享multiprocessing.Array字符串,以便每个进程可以使用相同的数据更新和读取该Array 我试过c_char_p ,它说使用byte字符串。 但是,对于此代码:

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()

输出与此不同:

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

对此:

[b'Hello World']
This ran

但我希望:

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

我想一个明显的解决方案是在每个进程之间共享一个公共文件,但我希望使用多个数组,这可能会有点乏味。 我想知道 Python 3.8 中目前最好的解决方案是什么。

对于此代码:

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)

它永远不会结束(即在进程开始后永远不会到达打印语句),输出是:

This ran

我不知道为什么。

这些值作为编码字符串(字节值)存储在array中,因此当您需要字符串值时,您必须对其进行解码

尝试这个:

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()

输出:

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

我不认为它应该在一般情况下工作。

基本上, c_char_p是一个指针,一个引用进程中内存位置的数字。 并且您不能期望指针在进程之间是可移植的。

由于 Python Process -es 从其父进程继承,它可能适用于在子进程启动之前创建的字符串。

但是您不能期望在子进程中创建一个新字符串,添加一个指向 Array 的指针并期望它在父进程中有效。 (反之亦然。)

使用PipeQueue可能是交换字符串数据的更好方法。

编辑1:

使用Pipe发送字符串列表的突变,例如作为元组(3, "new value") 这意味着列表中的第 3 项现在变成了"new value" 使用双工Pipe意味着Pipe两端都可以读取和应用传入的每条消息。

编辑2

另一种选择是使用multiprocessing.Manager 这将允许您共享listdict

暂无
暂无

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

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