如何在具有多个文件的文件夹上执行多线程处理?

时间:2018-11-28 21:46:06

标签: python multithreading

我想遍历python中的图像文件文件夹并对其做一些工作。所以它是这样开始的:

for image in os.listdir(imagePath):
    if image.endswith('.jpg'):
         <DO STUFF HERE>

我在该文件夹中有很多图像,并希望使用多线程来加快速度。每个图像都有一个单独的线程。我该怎么做?

3 个答案:

答案 0 :(得分:0)

您可以创建一个扩展threading.Thread类的类,然后在满足条件的情况下覆盖run以执行您要执行的任务。

然后使用listdir获取所有图像并对其进行迭代,为每个图像分配一个新线程。最后,启动每个线程。下面是上面描述的示例代码:

import threading
import os

class FileThread(threading.Thread):

    def __init__(self, image):
        threading.Thread.__init__(self)
        self.image = image

    def run(self):
        if image.endswith('.jpg'):
            # Do stuff

# List that will hold all threads.
threadList = []
# List that will hold all images.
images = os.listdir(imagePath)
# Assign each image to a thread.
for image in images:
    threadList.append(FileThread(image))
# Start threads.
for thread in threadList:
    thread.start()

另一种方法是使用multiprocessing模块并将每个图像分配给一个进程:

import multiprocessing as mp
import os

# The function that will apply to every image.
def imageFunc(image):
    if image.endsWith(".jpg"):
        # Do something

# An output queue that will hold the results.
output = mp.Queue()

# A list of processes that will perform the 'imageFunc' on each image.
processes = [mp.Process(target=imageFunc, args=(image)) for image in os.listdir(imagePath)]

# Starting all the processes...
for p in processes:
    p.start()

# ...and wait for them to finish.
for p in processes:
    p.join()

# Finally, retrieve the results from the above processes.
result = [output.get() for p in processes]

答案 1 :(得分:0)

我在想这样的事情:

#! /usr/bin/python3
import os
from multiprocessing import Process

def do_stuff(*args):
    print(*args)

if __name__ == '__main__':
    processes = []
    for f in os.listdir('.'):
        if f[-3:] == 'jpg':
            p = Process(target=do_stuff, args=[f])
            p.start()
            processes.append(p)
    for p in processes:
        p.join()

请小心...如果您使用args = f而不是args = [f],则会得到错误的结果

编辑:要传递其他arg,请使用元组,但删除[]:

import os
from multiprocessing import Process

def do_stuff(*args):
    print(*args)

if __name__ == '__main__':
    processes = []
    for f in os.listdir('.'):
        if f[-3:] == 'jpg':
            p = Process(target=do_stuff, args=(f, "hello"))
            p.start()
            processes.append(p)
    for p in processes:
        p.join()

答案 2 :(得分:0)

我认为,就像其他人所说的那样,您可能希望并行运行代码,这是通过多处理而不是python中的多线程完成的。最简单的方法可能是使用multiproccessing.Pool.map。您所要做的就是定义一个函数,该函数以文件名作为参数来处理一个文件。然后,将要处理的所有文件的列表传递给具有处理功能的pool.map函数。 Pool.map的返回将是结果列表:

from multiprocessing import Pool as ProcessPool
import os

def image_processor(image):
    # do stuff
    return results

if __name__ == "__main__":
    desired_file_list = [file_name for file_name in os.listdir("my_directory_path") if file_name.endswith(".jpg")]

    with ProcessPool(processes=8) as pool:
        results = pool.map(image_processor, desired_file_list)

    print(results)

processes关键字参数控制生成的进程数。