首页 > 解决方案 > 如何在并行线程中调用 sum 函数并将数组中的数字传递给 Python 中的函数?

问题描述

我正在用 Python 做一个小任务:

1-编写一个简单的加法函数,将两个给定的数字相加并打印它们的总和。

2-声明一个包含 10 个数字的数组。

3- 在并行线程中调用 sum 函数,并按照以下规则将数组上方的数字传递给函数:

--> sum(array[thread_id], array[9-thread_id])

我已经完成了第 1 步和第 2 步,但我不知道在第 3 步中该做什么。这是下面的代码:

import array
import multiprocessing
import threading
from multiprocessing import Process

# 1- write a simple add function that will add two given numbers and print their sum

x = 5
y = 10

def add(a,b):
    sum = int(a) + int(b)
    print ("The sum is: ", sum)
    
add(x,y)
    
# 2 Declare an array of 10 numbers
a_list = list(range(1, 11))
print ('an array of 10 numbers: '  + str(a_list))





# 3 call sum function in parallel threads and pass the numbers form above array to function as per following rules

# --> sum(array[thread_id], array[9-thread_id])

谁能帮我在第 3 步中做什么?我对并行线程(或多处理)知之甚少

标签: pythonpython-3.xmultithreadingparallel-processing

解决方案


在 Python 中,您可以像这样启动一个新线程

import threading

def function_to_run_in_thread(arg1, arg2): ...

threading.Thread(target=function_to_run_in_thread, args=("some", "arguments")).start()

你可以像这样开始一个新的过程

import multiprocessing

def function_to_run_in_subprocess(arg1, arg2): ...

multiprocessing.Process(target=function_to_run_in_subprocess, args=("some", "arguments")).start()

但是,以这种方式通过线程/多处理获得函数返回值并不是特别容易。最好使用 a ThreadPoolExecutoror ProcessPoolExecutorfromconcurrent.futures模块。

所以在你的情况下,我们可以做

# Both the ThreadPoolExecutor and ProcessPoolExecutor are basically interchangeable from an API perspective
from concurrent.futures import ThreadPoolExecutor as Pool
# from concurrent.futures import ProcessPoolExecutor as Pool

pool = Pool(10) # the argument is the number of threads/processes available

sum_futures = [pool.submit(add, *pair) for pair in zip(a_list, reversed(a_list))]

# We must explicitly wait for the calculation to finish for each add call
sum_results = [future.result() for future in sum_futures]

或者,我们也可以这样做


sum_results = list(pool.map(lambda args: add(*args), zip(a_list, reversed(a_list))))

更简洁


在 CPython(Python 的参考实现,您可能正在使用的那个)中,在给定时间只有一个线程可以持有全局解释器锁。这意味着在 CPython 解释器中运行的代码中的多线程只会为您执行不需要持有 GIL 的操作带来好处,例如

  • 阻塞网络/IO 操作
  • 在显式释放 GIL 的 C 扩展中运行某些代码

基本上这意味着在python中将两个数字相加的操作在使用多线程时不能真正并行执行。

然而,多重处理有其自身的缺点,其中之一pickle是需要序列化(使用)在进程之间传递值。有些值不能被腌制(例如 lambda 表达式),这可能是一个潜在的障碍。线程不受此限制,因为它们可以使用共享内存区域进行通信,这也快得多。


推荐阅读