繁体   English   中英

用于Python中multiprocessing.Array的元组

[英]Tuple for multiprocessing.Array in python

我在python中进行多重处理。 我想将元组列表放在multiprocessing.Array中,但是找不到元组的类型代码。

这是代码,我想知道如何在主函数中为arr编写“ type_of_tuple”。

from multiprocessing import Pool, Array

def thread_func(time, array):
    time.sleep(time)
    if len(array) > 0:
        print(array.pop(0))

def main(cpu_number):
    list = [("a","b"), ("c","d"), ("e","f")]
    arr = Array( type_of_tuple """ how to write this?""", list)

    for i in range(cpu_number):
        r = pool.apply_async(thread_func, args=(1000, arr))
        thread_list.append(r)

    for thread in thread_list:
        thread.wait()

if __name__ == "__main__":
    main(3)

您找不到它的原因是因为它不存在。 Array的全部要点是,它处理可以存储为“未装箱”二进制数据的简单,同质类型的数组。

元组是复合类型,可以容纳任意数量的任何类型的值。 因此,您不能将其放入Array

实际上,您也不能将字符串放入数组中,因为字符串具有可变数量的字符。 每个都是不同的大小。 (而且,如果这是Python 3,那就更糟糕了,因为字符可以是1、2或4个字节…)

最重要的是,数组的长度是固定的。 您仍然无法从中pop值。

因此,您将需要找到另一种共享数据的方式。

如果您对C足够了解,可以将您的字符串元组映射到char* struct ,则可以使用shared_ctypes

或者,您可以编写一个函数,在一侧将元组编码为固定大小的值(然后将其切成字符数组),在另一侧将其解码。

但是我怀疑,如果您按照文档的建议去做,并找到一种以消息传递而不是共享内存的方式编写代码的方法,您会发现生活简单得多。

由于您唯一需要共享的变异是让每个作业从末端pop一个值,以使其他作业不会看到相同的值,因此显而易见的答案是使用Queue ,因为这正是它的作用。

或者,甚至更简单,只需使用诸如map的高级方法之一而不是apply ,就可以管理队列并确保每个作业恰好获得一个值,因此您甚至不必考虑它。 例如:

def thread_func(time, value):
    time.sleep(time)
    print(value)

def main(cpu_number):
    values = [("a","b"), ("c","d"), ("e","f")]
    results = pool.imap_unordered(partial(thread_func, 1000), values[:cpu_number])
    for result in results:
        pass

if __name__ == "__main__":
    main(3)

(作为附带说明,我不确定为什么将任务数限制为CPU数。通常,您创建一个Pool(cpu_number)并将所有任务Pool(cpu_number)队列。如果您只想要恰好执行3个任务,您甚至根本不需要一个池,只需在Process上运行每个池即可。)

要回答您的问题,而不关心逻辑,您应该改用ctypes结构:

from ctypes import Structure, POINTER, byref, c_ubyte, cast, create_string_buffer
from multiprocessing import Pool, Array


class SomeTuple(Structure):
    _fields_ = [
        ('a', POINTER(c_ubyte)),
        ('b', POINTER(c_ubyte))
    ]


def thread_func(time, array_):
    time.sleep(time)
    if len(array_) > 0:
        print(array_.pop(0))

def main(cpu_number):
    thread_list = []
    value_list = [
        SomeTuple(cast(create_string_buffer(b"a"), POINTER(c_ubyte)), cast(create_string_buffer(b"b"), POINTER(c_ubyte))),
        SomeTuple(cast(create_string_buffer(b"c"), POINTER(c_ubyte)), cast(create_string_buffer(b"d"), POINTER(c_ubyte))),
        SomeTuple(cast(create_string_buffer(b"e"), POINTER(c_ubyte)), cast(create_string_buffer(b"f"), POINTER(c_ubyte)))
    ]
    arr = Array(SomeTuple, value_list)

    with Pool(processes=cpu_number) as pool:
        for _ in range(cpu_number):
            r = pool.apply_async(thread_func, args=(1000, arr))
            thread_list.append(r)

    for thread in thread_list:
        thread.wait()

if __name__ == "__main__":
    main(3)

暂无
暂无

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

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