想使用多线程优化批量excel比对,多个线程同时进行多个Excel比对,每个excle比对耗时远大于单线程处理
child_thread_compare是对比业务,若我限制子线程数为1,效率和单线程耗时一致
2022-09-27_15:31:22 2022-09-27_15:43:47 多线程(10个) 13.5分钟
2022-09-27_16:03:11 2022-09-27_16:14:24 多线程(3个) 11分钟
2022-09-27_15:45:05 2022-09-27_15:55:35 单线程 10.5分钟
单线程或子线程为1时,10M的excle比对耗时2分钟;子线程为10时,10M的excle比对耗时11分钟
t = threading.Thread(target=self.child_thread_compare,
args=(same_file_name, old_file_name, new_file_name, result_file_name, name, file1_name, file2_name)) # 另启一个线程比对
self.running_thread_name.append(same_file_name)
t.start()
多线程(10个) :文件[\20090111\tstockinfo]对比结果[失败],耗时[00:11:51]
单线程:文件[\tstockinfo]对比结果[成功],耗时[00:01:39]
这种操作文件的过程用多进程比较合适
1.如果是网络通信之类的应用,由于需要等待外部IO响应,使用多线程是可以极大的提高效率的
2.如果你要做的基本是内存操作,那么单线程本身并没有浪费时间,多线程能够提高效率的前提是你的cpu是多核的,可以多任务并行处理
3.根据不同cpu的特性不同,你的线程数量不应该大于cpu核心数量或者cpu核心数量x2,否则会造成线程排队等待,更消耗时间
4.如果你一个文件单线程处理需要2分钟,按顺序处理10个就是20分钟;而10个线程一起处理需要11分钟,其实总体上还是节约了时间的
对文件进行处理的时候,多线程同时处理多个文件可能会导致io异常
问题已解决,解决方案:
对于系统文件操作改为多进程处理。
class ProcessCompare():
'''对比操作,具体代码不做展示'''
pass
#以下为主线程中部分代码
# 多进程处理代码
self.queues = Queue() # 用于进程之间传递信息(主要是传回对比结果)
a = threading.Thread(target=self.get_queues) # 先开个线程专门等待进程间消息传递(必须单独开线程queues.get(True)会导致线程阻塞)
a.start()
t = multiprocessing.Process(target=ProcessCompare,args=(same_file_name, old_file_name, new_file_name,result_file_name,)
self.running_thread_name.append(same_file_name) # 启动进程用于比对(有限制最大进程3,4个进程后CPU耗尽电脑卡了)
t.start()
def get_queues(self):
self.queues_break = False
result_num = 0
while True:
if self.queues_break:
break
info_dict = self.queues.get(True)
result_num += 1
print('queues_info=', info_dict)
name = info_dict.get('name')
this_result = info_dict.get('result')
time = info_dict.get('time')
error_info = info_dict.get('error_info')
if error_info:
self.text_signal(error_info, colour='red', level='ERROR')
if this_result:
self.text_signal( '文件[%s]对比结果[%s],耗时[%s]' % (name, '成功', time), level='INFO')
else:
self.result = False
self.text_signal( '文件[%s]对比结果[%s],耗时[%s]' % (name, '失败', time), colour='red', level='ERROR')
if name in self.running_thread_name:
self.running_thread_name.remove(name)
if result_num >= self.muiti_num: # 获取到的数量大于等于要对比的数量退出线程
break