如何为Python递归积分代码添加线程?修改后结果仍错误
问题:为自适应梯形积分递归代码添加线程后无法正常运行
我尝试给一段实现自适应梯形积分的Python递归代码添加线程,但始终无法正常运行。老师建议用存储参数的列表来实现,我没成功;之后尝试不改动递归逻辑直接加线程,结果还是错误。
原始代码(正常运行)
a = 1 b = 3 E = 0.07 def f(x): return x**4 def quad(left, right, fleft, fright, lr_area): mid = (left + right)/2 fmid = f(mid) l_area = ((fleft + fmid)*(mid - left)/2) r_area = ((fmid + fright)*(right - mid)/2) if abs((l_area + r_area) - lr_area) > E: l_area = quad(left, mid, fleft, fmid, l_area) r_area = quad(mid, right, fmid, fright, r_area) return l_area + r_area S = quad(a, b, f(a), f(b), (f(a) + f(b))*(b-a)/2) print(S)
修改后的代码(无法正常运行)
import threading import time a = 1 b = 3 E = 0.07 def f(x): return x**4 def quad(left, right, fleft, fright, lr_area): mid = (left + right)/2 fmid = f(mid) l_area = ((fleft + fmid)*(mid - left)/2) r_area = ((fmid + fright)*(right - mid)/2) atribute_list = [] if abs((l_area + r_area) - lr_area) > E: l_area1 = threading.Thread(target=quad, args=(left, mid, fleft, fmid, l_area,)) r_area1 = threading.Thread(target=quad, args=(mid, right, fmid, fright, r_area,)) l_area1.start() r_area1.start() l_area1.join() r_area1.join() time.sleep(1) print(atribute_list) return atribute_list S = quad(a, b, f(a), f(b), (f(a) + f(b))*(b-a)/2) print(S)
问题分析与修复方案
你的修改代码有两个核心问题:
- 普通
Thread无法直接返回函数执行结果,你定义的atribute_list始终为空,导致输出错误。 - 原递归逻辑被完全破坏——原代码通过递归返回子区间积分值并累加,修改后直接返回空列表,完全偏离了计算逻辑。
方案1:用ThreadPoolExecutor简化线程管理(推荐)
concurrent.futures.ThreadPoolExecutor可以方便地获取线程返回值,完美衔接原递归逻辑:
import concurrent.futures a = 1 b = 3 E = 0.07 def f(x): return x**4 def quad(left, right, fleft, fright, lr_area): mid = (left + right)/2 fmid = f(mid) l_area = ((fleft + fmid)*(mid - left)/2) r_area = ((fmid + fright)*(right - mid)/2) if abs((l_area + r_area) - lr_area) > E: # 用线程池并行执行左右子区间的递归计算 with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor: # 提交任务并获取Future对象 future_l = executor.submit(quad, left, mid, fleft, fmid, l_area) future_r = executor.submit(quad, mid, right, fmid, fright, r_area) # 提取线程返回的计算结果 l_area = future_l.result() r_area = future_r.result() return l_area + r_area S = quad(a, b, f(a), f(b), (f(a) + f(b))*(b-a)/2) print(S)
方案2:手动用可变对象存储线程结果
如果必须用原生Thread实现,可以通过可变对象(比如列表)传递结果(因为可变对象在线程中的修改会同步到外部):
import threading a = 1 b = 3 E = 0.07 def f(x): return x**4 def quad(left, right, fleft, fright, lr_area): mid = (left + right)/2 fmid = f(mid) l_area = ((fleft + fmid)*(mid - left)/2) r_area = ((fmid + fright)*(right - mid)/2) if abs((l_area + r_area) - lr_area) > E: # 用列表存储结果,列表是可变对象,线程可修改 l_result = [0] r_result = [0] def calc_left(): l_result[0] = quad(left, mid, fleft, fmid, l_area) def calc_right(): r_result[0] = quad(mid, right, fmid, fright, r_area) l_thread = threading.Thread(target=calc_left) r_thread = threading.Thread(target=calc_right) l_thread.start() r_thread.start() l_thread.join() r_thread.join() l_area = l_result[0] r_area = r_result[0] return l_area + r_area S = quad(a, b, f(a), f(b), (f(a) + f(b))*(b-a)/2) print(S)
内容的提问来源于stack exchange,提问作者Иван Шакура
相关产品推荐
相关产品推荐

