python中同一函数的多个实例异步

时间:2018-11-09 19:29:32

标签: python python-3.x multithreading asynchronous python-asyncio

我有一个小脚本,可以执行一些简单的任务。运行Python 3.7。

其中一项任务是将一些文件合并在一起,这可能会花费一些时间。

它循环遍历多个目录,然后每个目录都传递给该函数。该功能仅循环遍历文件并将其合并。

而不是等待它完成一个目录,然后进入下一个目录,然后等待,然后进入下一个目录,等等...

我想利用功能/核心/线程使脚本一次将多个目录中的PDF合并在一起,这将节省时间。

我有这样的东西:

if multi_directories:
    if os.path.isdir('merged'):
        pass
    else:
        os.makedirs('merged')
    for directory in multi_directories:
        merge_pdfs(directory)

我的合并PDF功能如下:

def merge_pdfs(directory):
    root_dir = os.path.dirname(os.path.abspath(__file__))
    merged_dir_location = os.path.join(root_dir, 'merged')
    dir_title = directory.rsplit('/', 1)[-1]
    file_list = [file for file in os.listdir(directory)]
    merger = PdfFileMerger()
    for pdf in file_list:
        file_to_open = os.path.join(directory, pdf)
        merger.append(open(file_to_open, 'rb'))
        file_to_save = os.path.join(
            merged_dir_location,
            dir_title+"-merged.pdf"
        )
    with open(file_to_save, "wb") as fout:
        merger.write(fout)
    return True

这很好用-但在目录中包含大量PDF的某些情况下,merge_pdfs运行缓慢。

基本上-我希望能够遍历multi_directories并为每个目录创建一个新线程或进程,并同时合并PDF。

我看过asynciomultithreading以及无处不在的小片段,但似乎无法正常工作。

1 个答案:

答案 0 :(得分:3)

您可以执行以下操作:

from multiprocessing import Pool
n_processes = 2
...
if multi_directories:
    if os.path.isdir('merged'):
        pass
    else:
        os.makedirs('merged')
    pool = Pool(n_processes)
    pool.map(merge_pdfs, multi_directories)

如果瓶颈是CPU使用率,应该会有所帮助。但是,如果瓶颈是HDD,可能会使情况变得更糟,因为从一个物理HDD并行读取多个文件通常比连续读取它们要慢。尝试使用不同值的 n_processes

顺便说一句,使用 list()file_list = list(os.listdir(directory))来使列表可迭代。由于 listdir()返回 List ,因此您只需编写file_list = os.listdir(directory)