如何在Python中创建字符串的多处理数组?

2024-10-04 01:34:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在ubuntu上用Python3创建一个字符串的多处理数组

如何声明数组?我发现我显然可以使用ctypes(特别是c_wchar_p表示字符串) 因此,我尝试了以下方法:

from ctypes import c_wchar_p
from multiprocessing import Array

string_array = Array(c_wchar_p,range(10))

Tags: 方法字符串fromimport声明stringubunturange
1条回答
网友
1楼 · 发布于 2024-10-04 01:34:39

实际上,您不能轻易地使用c_wchar_p。当然,将执行您拥有的3条语句,但在共享内存中创建数据的目的是让多个进程可以访问和更新该数据,问题是如果您执行以下操作

string_array[0] = 'abc'

。。。您将在共享内存中存储特定于一个特定地址空间的字符串地址,当该字符串被另一个地址空间中的进程引用时,它将是无效的地址。{}的文档用以下注释说明了这一点:

Note: Although it is possible to store a pointer in shared memory remember that this will refer to a location in the address space of a specific process. However, the pointer is quite likely to be invalid in the context of a second process and trying to dereference the pointer from the second process may cause a crash.

您可以尝试创建一个字符数组,其大小为您希望存储的最大字符串大小。下面的代码演示了这一点:

from ctypes import c_wchar
from multiprocessing.sharedctypes import RawArray
from multiprocessing import Pool

def init_pool(the_arr):
    global arr
    arr = the_arr

def worker():
    print(arr[0].value)
    print(arr[1].value)
    arr[2].value = 'It works!'

def main():
    # create a list of 10 RawArrays, each one capable of holding 20-character strings
    # The list itself is not meant to be modifiable, only the contained "strings"
    arr = [RawArray(c_wchar, 20) for _ in range(10)]
    arr[0].value = 'abc'
    arr[1].value = 'defghijklmn'
    # initialize process pool's processes' global variable arr
    pool = Pool(2, initializer=init_pool, initargs=(arr,))
    # worker function will execute in a different address space:
    pool.apply(worker)
    print(arr[2].value)

# Required for Windows:
if __name__ == '__main__':
    main()

印刷品:

abc
defghijklmn
It works!

如果您需要一个可修改的列表(能够增长和收缩),那么您应该使用一个托管列表,并且忘记共享内存(如果您有很多访问,这会运行得慢一些,但更“自然”):

from multiprocessing import Pool, Manager

def init_pool(the_arr):
    global arr
    arr = the_arr

def worker():
    print(arr[0])
    print(arr[1])
    arr.append('It works!')

def main():
    arr = Manager().list(['abc', 'defghijklmn'])
    # initialize process pool's processes' global variable arr
    pool = Pool(2, initializer=init_pool, initargs=(arr,))
    pool.apply(worker)
    print(arr[2])

# Required for Windows:
if __name__ == '__main__':
    main()

相关问题 更多 >