gpt4 book ai didi

python - 同时解析,python

转载 作者:行者123 更新时间:2023-11-28 20:46:59 25 4
gpt4 key购买 nike

我有一个 python 程序,可以按顺序解析 30,000 多个文件。

有没有办法将其分解为多个线程(这是正确的术语吗?)并同时解析该文件的 block 。假设有 30 个算法,每个算法解析 1000 个文件。

最佳答案

这很简单。

您可以显式创建 30 个线程并为每个线程指定 1000 个文件名。

但是,更简单的是,您可以创建一个包含 30 个线程的池,并让它们为一个具有 30000 个文件名的线程提供服务。这为您提供了自动负载平衡——如果一些文件比其他文件大得多,您将不会有一个线程完成而另一个线程只完成了 10%。

concurrent.futures模块为您提供了一种并行执行任务的好方法(包括将参数传递给任务并接收结果,如果需要,甚至可以是异常)。如果您使用的是 Python 2.x 或 3.1,则需要安装反向端口 futures .然后你只需这样做:

with concurrent.futures.ThreadPoolExecutor(max_workers=30) as executor:
results = executor.map(parse_file, filenames)

现在,30 名 worker 可能太多了。您将淹没硬盘驱动器及其驱动程序,并最终让您的大部分线程等待磁盘寻道。但一小部分可能是值得做的。调整 max_workers 并测试时间并查看系统的最佳位置是非常容易的。


如果您的代码执行的 CPU 工作多于 I/O 工作——也就是说,它花在解析字符串和构建复杂结构等方面的时间多于从磁盘读取的时间——那么线程至少无济于事在 CPython 中,由于全局解释器锁。但您可以通过使用流程来解决这个问题。

从代码的角度来看,这很简单:只需将 ThreadPoolExecutor 更改为 ProcessPoolExecutor

但是,如果您要返回大型或复杂的数据结构,那么跨进程边界对它们进行序列化所花费的时间可能会消耗甚至压垮您的储蓄。如果是这种情况,您有时可以通过批处理更大的作业来改进:

def parse_files(filenames):
return [parse_file(filename) for filename in filenames]
with concurrent.futures.ThreadPoolExecutor(max_workers=30) as executor:
results = executor.map(parse_files, grouper(10, filenames))

但有时您可能需要降低到较低级别并使用 multiprocessing模块,具有进程间内存共享等功能。


如果你不能/不想使用 futures,2.6+ 有 multiprocessing.Pool对于普通处理器池,以及名称为 multiprocessing.ThreadPool(未记录)或 multiprocessing.dummy.Pool(已记录但丑陋)的具有相同接口(interface)的线程池。

在这种微不足道的情况下,普通池和执行器之间确实没有区别。而且,如上所述,在非常复杂的情况下,multiprocessing 可以让您深入了解。在中间,futures 通常更简单。但这两者都值得学习。

关于python - 同时解析,python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19936835/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com