Python 为什么多线程不能加速我的程序?
我有一个大的文本文件需要处理。我首先将所有文本读入一个列表,然后使用ThreadPoolExecutor启动多个线程来处理它。此处未列出在process_text()中调用的两个函数:is_channel和get_relations() 我在Mac上,我的观察表明它并没有真正加快处理速度(cpu有8个内核,只使用了15%的cpu)。如果函数is_channel或get_关系中存在性能瓶颈,那么多线程将不会有多大帮助。这就是没有绩效提升的原因吗?我是否应该尝试使用多处理来提高速度,而不是多线程Python 为什么多线程不能加速我的程序?,python,multithreading,python-multiprocessing,python-multithreading,Python,Multithreading,Python Multiprocessing,Python Multithreading,我有一个大的文本文件需要处理。我首先将所有文本读入一个列表,然后使用ThreadPoolExecutor启动多个线程来处理它。此处未列出在process_text()中调用的两个函数:is_channel和get_relations() 我在Mac上,我的观察表明它并没有真正加快处理速度(cpu有8个内核,只使用了15%的cpu)。如果函数is_channel或get_关系中存在性能瓶颈,那么多线程将不会有多大帮助。这就是没有绩效提升的原因吗?我是否应该尝试使用多处理来提高速度,而不是多线程 d
def process_file(file_name):
all_lines = []
with open(file_name, 'r', encoding='utf8') as f:
for index, line in enumerate(f):
line = line.strip()
all_lines.append(line)
# Classify text
all_results = []
with ThreadPoolExecutor(max_workers=10) as executor:
for index, result in enumerate(executor.map(process_text, all_lines, itertools.repeat(channel))):
all_results.append(result)
for index, entities_relations_list in enumerate(all_results):
# print out results
def process_text(text, channel):
global channel_text
global non_channel_text
is_right_channel = is_channel(text, channel)
entities = ()
relations = None
entities_relations_list = set()
entities_relations_list.add((entities, relations))
if is_right_channel:
channel_text += 1
entities_relations_list = get_relations(text, channel)
return (text, entities_relations_list, is_right_channel)
non_channel_text += 1
return (text, entities_relations_list, is_right_channel)
首先要做的是找出需要多少时间:
- T1>>T2=>IO绑定
- T2>>T1=>CPU受限
- T1和T2接近=>两者都不接近。
通过
我的意思是x明显大于yx>>y
- 运行代码以在线程中读取文件本身,并让它将行推送到
,而不是列表。队列
此线程在从文件读取完毕后,在末尾插入一个None。这对于告诉工人他们可以停止工作很重要 - 现在运行处理人员并将队列传递给他们
- 工人们在循环中不断地从队列中读取数据并处理结果。与读取器线程类似,这些工作人员将结果放入队列中。 一旦线程遇到None,它将停止循环并将None重新插入队列(以便其他线程可以自行停止)
- 打印部分也可以在一根线中完成
- 将整个文件读取到列表中
- 根据线程数将列表划分为索引范围。
示例:如果文件总共有100行,我们使用10个线程
然后是0-9,10-19。。。。90-99是索引范围
将完整列表和这些索引范围传递给线程以处理每个集合。由于您没有修改原始列表,因此此操作有效。
这种方法比为每一行运行worker效果更好
- 处理前将文件拆分为多个文件
- 为每个文件运行一个新进程
- 每个进程获取它应该读取和处理的文件的路径
- 这需要在末尾合并所有结果/文件的附加步骤
流程创建部分可以在python中使用
modulemultiprocessing
或者从驱动程序脚本为每个文件生成python进程,如shell脚本
- 多处理:当处理存储在磁盘上的巨大文本文件(GBs)时(就像您正在做的)
- 线程(方法1):从多个数据库读取数据时。因为这比CPU更受IO限制(我使用了多个生产者线程和多个消费者线程)
频道文本
和非频道文本
@Prune的访问。他正在使用共享变量频道文本
和非频道文本
。多进程将使其更加复杂,需要与主进程进行进程间通信。@marlon Yes。递增变量不是原子的。看见