我正在尝试将从大文件行中提取的信息发送到某个服务器上运行的进程。
为了加快速度,我想在一些并行的线程中做到这一点。
使用concurrent.futures的Python 2.7 backport我尝试了这个:
f = open("big_file")
with ThreadPoolExecutor(max_workers=4) as e:
for line in f:
e.submit(send_line_function, line)
f.close()
然而,这是有问题的,因为所有期货都会立即提交,因此我的机器内存不足,因为整个文件会被加载到内存中。
我的问题是,如果有一个简单的方法可以在免费工作人员可用时提交新的未来。
答案 0 :(得分:1)
您可以使用
迭代文件的块for chunk in zip(*[f]*chunksize):
(这是grouper recipe的一个应用程序,它将来自迭代器f
的项目收集到大小为chunksize
的组中。注意:这不会立即消耗整个文件{ {1}}在Python3中返回一个迭代器。)
zip
现在,在评论中你正确地指出这不是最佳的。 可能会有一些工人需要很长时间,并且占用了大量的工作。
通常情况下,如果对工作人员的每次呼叫花费大致相同的时间,那么这不是什么大问题。但是,这是一种按需推进文件句柄的方法。它使用import concurrent.futures as CF
import itertools as IT
import logging
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.DEBUG,
format='[%(asctime)s %(threadName)s] %(message)s',
datefmt='%H:%M:%S')
def worker(line):
line = line.strip()
logger.info(line)
chunksize = 1024
with CF.ThreadPoolExecutor(max_workers=4) as executor, open("big_file") as f:
for chunk in zip(*[f]*chunksize):
futures = [executor.submit(worker, line) for line in chunk]
# wait for these futures to complete before processing another chunk
CF.wait(futures)
通知threading.Condition
推进文件句柄。
sprinkler