Python处理列表/队列中的项目并保存进度

时间:2018-08-30 06:16:52

标签: python multithreading save queue progress

如果我有大约10+百万个小任务要在python中处理(转换图像等),如何在处理崩溃的情况下创建队列并<保存>保存进度。明确地说,我该如何保存进度或停止任何所需的过程,并从最后一点继续进行处理。

在这种情况下还要如何处理多个线程?

通常的问题是如何将已处理数据的进度保存到文件中。问题是,如果文件非常小,每次迭代后保存文件的时间将比处理自身的时间长。

谢谢!

(抱歉,我的英语不太清楚)

2 个答案:

答案 0 :(得分:0)

首先,我建议不要使用多线程。请使用多处理。由于涉及到计算密集型任务的GIL,多个线程无法在python中同步工作。

要解决保存结果的问题,请按以下顺序操作

  1. 获取列表中所有文件的名称,并将该列表分成多个块。
  2. 现在为每个进程分配一个块。
  3. 每隔1000个步骤,将已处理文件的名称追加到系统上的某个文件(例如monitor.txt)上(假设在发生故障的情况下可以再次处理1000个文件)。
  4. 如果发生故障,请跳过每个进程保存在monitor.txt中的所有文件。

每个进程可以有monitor_1.txt,monitor_2.txt ...,因此您不必阅读每个进程的整个文件。

遵循要点可能会对您有所帮助。您只需要为第四点添加代码。 https://gist.github.com/rishibarve/ccab04b9d53c0106c6c3f690089d0229

答案 1 :(得分:0)

诸如保存文件之类的I / O操作始终相对较慢。如果必须处理大量文件,则无论使用多少线程,都将花费很长的I / O时间。

最简单的方法是使用多线程而不是多处理,并让操作系统的调度程序将其全部解决。 The docs对如何设置线程有很好的解释。一个简单的例子是

from threading import Thread

def process_data(file_name):
    # does the processing
    print(f'processed {file_name}')

if __name__ == '__main__':
    file_names = ['file_1', 'file_2']
    processes = [Thread(target=process_data, args=(file_name,)) for file_name in file_names]

    # here you start all the processes
    for proc in processes:
        proc.start()

    # here you wait for all processes to finish
    for proc in processes:
        proc.join()

一种可能更快的解决方案是创建一个单独的进程来执行I / O。然后,您使用multiprocessing.Queue将来自“数据处理线程”的文件排队,然后让I / O线程拾取这些文件并一个接一个地处理它们。

通过这种方式,I / O永远不必休息,这将接近最佳状态。我不知道这是否会比基于线程的解决方案产生更大的优势,但与并发通常一样,最好的发现方法是使用自己的应用程序进行一些基准测试。

需要注意的一个问题是,如果数据处理快得多,那么Queue可能会变得非常大。 可能会对性能产生影响,具体取决于您的系统。一种快速的解决方法是在队列变大时暂停数据处理。

记住要使用

在脚本中用Python编写所有多处理代码。
if __name__ == '__main__':
    # mp code

警惕,请注意,某些IDE不能与并发Python代码配合使用。安全的选择是通过从终端执行代码来测试您的代码。