我正试图在ubuntu上用python 3创建一个字符串的多处理数组。
如何声明数组?我发现我显然可以使用ctypes(特别是字符串的c_wchar_p(所以我尝试了以下方法:
from ctypes import c_wchar_p
from multiprocessing import Array
string_array = Array(c_wchar_p,range(10))
实际上,您无法轻松使用c_wchar_p
。当然,您拥有的3条语句会执行,但在共享内存中创建数据的目的是让多个进程可以访问和更新这些数据,问题是,如果您执行以下操作。。。
string_array[0] = 'abc'
您将把特定于一个特定地址空间的字符串的地址存储到共享内存中,当该字符串被不同地址空间中的进程引用时,它将是一个无效地址。multiprocessing.sharedctypes
的文档通过以下注释对此进行了说明:
注意:虽然可以在共享内存中存储指针,但请记住,这将指向特定进程地址空间中的一个位置。然而,指针在第二个进程的上下文中很可能是无效的,尝试从第二个过程中取消引用指针可能会导致崩溃。
您可以尝试创建一个字符数组,其大小是您希望存储的最大字符串大小。以下代码演示了这一点:
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()