Kivy中使用Concurrent Futures实现多进程提速问题
问题分析与解决方案
你的代码存在两个核心问题导致多进程无法提速:一是多进程与Kivy启动的冲突(Windows系统下子进程会重复执行脚本逻辑),二是大对象序列化传递的开销抵消了并行优势。以下是修复后的代码及说明:
修复后的代码
import concurrent.futures from kivy.app import App from kivy.lang import Builder from kivy.uix.boxlayout import BoxLayout import math import time kv = ''' <GUI>: Button: text: 'press to run calculation' on_press: root.do_process() ''' def func3(numbers): # 用列表推导式替代循环append,提升计算效率 return [math.sqrt(number ** 5) for number in numbers] Builder.load_string(kv) class GUI(BoxLayout): def do_process(self): var = 10000000 # 提前生成一次大列表,避免重复创建和序列化开销 data_list = list(range(var)) # 单进程耗时测试 start2 = time.time() f1 = func3(data_list) f2 = func3(data_list) f3 = func3(data_list) f4 = func3(data_list) f5 = func3(data_list) end2 = time.time() # 多进程耗时测试 start3 = time.time() # 显式使用CPU核心数(默认值,可根据需求调整) with concurrent.futures.ProcessPoolExecutor() as executor: # 批量提交任务,复用同一个大列表 futures = [executor.submit(func3, data_list) for _ in range(5)] # 在Executor上下文内获取结果,避免资源泄漏 results = [future.result()[3] for future in futures] end3 = time.time() print('单进程耗时:', end2 - start2) print('多进程耗时:', end3 - start3) class MyApp(App): def build(self): return GUI() if __name__ == '__main__': # 仅主进程启动Kivy应用,子进程导入脚本时不会执行此块 MyApp().run()
关键修改点
解决多进程与Kivy的冲突
严格将MyApp().run()限制在if __name__ == '__main__'块内。Windows系统下多进程采用spawn模式,子进程会重新导入脚本,但不会执行该判断块内的代码,避免子进程重复启动Kivy应用,确保子进程仅专注于计算任务。削减大对象传递开销
提前生成一次1000万元素的data_list,所有多进程任务复用该列表,避免重复创建大列表以及多次序列化/反序列化大对象的开销——这是原代码多进程无法提速的核心原因。优化计算函数
将func3的循环append改为列表推导式,Python原生优化的列表推导式比手动循环执行效率更高,进一步压缩计算耗时。
效果验证
修改后运行代码,观察CPU使用率会发现多进程模式下多个核心被占用,耗时会比单进程模式减少约40%-70%(取决于CPU核心数)。
内容的提问来源于stack exchange,提问作者BH10001
相关产品推荐
相关产品推荐

