使用多处理器时如何在字典中重新添加数字

Posted

技术标签:

【中文标题】使用多处理器时如何在字典中重新添加数字【英文标题】:How I can re-add numbers inside dictionary while using multiprocessoring 【发布时间】:2021-12-31 00:12:30 【问题描述】:

我想构建一个使用多处理的程序。总体任务是将数字从 1 加到 17。使用某种“级别”

这里有一些例子:

            55       <- level 4

       36        19  <- level 3

   10      26    19  <- level 2

 3   7   11  15  19  <- level 1

1 2 3 4 5 6 7 8 9 10 <- level 0

如您所见,我想添加两个相邻的数字,这是绝对必要的,它必须通过多处理器来完成。我已经完成了第 1 级。现在,我不知道如何继续它,这是给你的问题 - 既然我的流程已经完成,我该如何循环它以在所有级别上完成它?这是我的一些代码:

我有字典

def divide_test(dict):
index = 0
print(len(starting_list))

for i in range(1, len(starting_list), 2):
    temporary = []

    temporary.append(starting_list[i - 1])
    temporary.append(starting_list[i])
    print(f"INDEX = i, S1 starting_list[i - 1], S2 starting_list[i]")
    dict[index] = temporary
    index += 1

# Last index couldn't be added to rest of the numbers, so I have to save it for later usage.
if None in dict.values():
    last_key = next(reversed(dict.keys()))
    dict[last_key] = starting_list[-1]

print("\n\n\n")
for key, value in dict.items():
    print(f"KEY key, VALUE value")

return dict

Console output for code from above:
INDEX = 1, S1 1, S2 2
INDEX = 3, S1 3, S2 4
INDEX = 5, S1 5, S2 6
INDEX = 7, S1 7, S2 8
INDEX = 9, S1 9, S2 10
INDEX = 11, S1 11, S2 12
INDEX = 13, S1 13, S2 14
INDEX = 15, S1 15, S2 16

计算这些数字的函数:

def calculate(key, dict):
temporary = []

for values in dict[key]:
    temporary.append(values)
new_number = sum(temporary)
dict[key] = new_number
temporary.clear()

主要

if __name__ == '__main__':
manager = multiprocessing.Manager()
dictionary = manager.dict()

fill_starting_list()
# processes = how_many_processes()
append_lists_to_dictionary((len(starting_list) // 2), dictionary)
divide_test(dictionary)

processes = []
for process_index in range(len(starting_list) // 2):
    p = multiprocessing.Process(target=calculate, args=(process_index, dictionary))
    p.start()
    processes.append(p)

for process in processes:
    process.join()

进程完成后的控制台输出:

TEST 0: 3, 1: 7, 2: 11, 3: 15, 4: 19, 5: 23, 6: 27, 7: 31, 8: 17

【问题讨论】:

我希望奇怪的编辑是个意外。请记住,*** 是关于制作一个持久的 Q/A 对集合。 请不要通过破坏您的帖子为他人增加工作量。通过在 Stack Exchange (SE) 网络上发帖,您已根据 CC BY-SA license 授予 SE 分发内容的不可撤销权利(即无论您未来的选择如何)。根据 SE 政策,分发非破坏版本。因此,任何破坏行为都将被撤销。请参阅:How does deleting work? …。如果允许删除,则帖子下方左侧有一个“删除”按钮,但仅在浏览器中,而不是移动应用程序中。 【参考方案1】:

您是否正在寻找这样的东西:

import multiprocessing as mp

def fill_starting_list():
    starting_list = list(range(1, 18))
    print(f"Length len(starting_list) list starting_list")
    return starting_list

def calculate(numbers):
    return sum(numbers)

if __name__ == "__main__":
    
    numbers = fill_starting_list()
    print(f"Sum calculated by 'sum': sum(numbers)")
    while len(numbers) > 1:
        slices = (numbers[i:i + 2] for i in range(0, len(numbers), 2))
        with mp.Pool() as pool:
            numbers = pool.map(calculate, slices)
            print(numbers)
    print(f"Sum calculated by recursive multiprocessing: numbers[0]")

输出:

Length 17 list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]
Sum calculated by 'sum': 153
[3, 7, 11, 15, 19, 23, 27, 31, 17]
[10, 26, 42, 58, 17]
[36, 100, 17]
[136, 17]
[153]
Sum calculated by recursive multiprocessing: 153

我在这里使用Poolmap 结合的进程,而不是单独的进程,因为它更容易。

正如@FMc 所指出的,不需要使用额外的函数caluculate,只需使用sum(也删除了fill_starting_list 函数):

import multiprocessing as mp

if __name__ == "__main__":
    
    numbers = list(range(1, 18))
    print(f"Length len(numbers) list numbers")
    print(f"Sum calculated by 'sum': sum(numbers)")
    while len(numbers) > 1:
        slices = (numbers[i:i + 2] for i in range(0, len(numbers), 2))
        with mp.Pool() as pool:
            numbers = pool.map(sum, slices)
            print(numbers)
    print(f"Sum calculated by recursive multiprocessing: numbers[0]")

【讨论】:

你能解释一下这段代码吗?切片 = (数字[i:i + 2] @SlipperyBarrel 这是一个生成器表达式,生成长度为 2 的 numbers 列表切片。你可以用slices = [numbers[i:i + 2] for i in range(0, len(numbers), 2)]替换它,然后print(slices)来查看它。 好答案 (+1)。小细节:calculate() 不需要,因为pool.map(sum, slices) 会做同样的事情。 @SlipperyBarrel 我看到你没有接受我的回答。这绝对没问题!但如果你能澄清原因,我会很高兴。也许我可以调整答案以使其更好。

以上是关于使用多处理器时如何在字典中重新添加数字的主要内容,如果未能解决你的问题,请参考以下文章

多处理:如何在多个进程之间共享一个字典?

如何在使用多处理时将数据添加到 json 文件?

如何在类中嵌套多处理管理器字典

多处理进程对象中的字典解包

请问如何在一个CDLINUX中添加BEINI的字典?

如何重新运行将在字典中切换变量并再次运行其自身的函数?