【问题标题】:multiprocessing ThreadPool reading and writing files多处理ThreadPool读写文件
【发布时间】:2022-01-25 22:07:00
【问题描述】:

我有超过 10000 个文件需要打开,其中一些我需要删除部分数据 试图用线程池来做,但从它开始我认为它不起作用

from multiprocessing.pool import ThreadPool

def readwrite(file):
    with open(file,'rb') as f:
        #check something
    #if check something is True
    #else return
    with open(new_file,'wb') as f:
        with open(file,'rb') as g:
             #here i write only the lines i need from the first file
pool = ThreadPool(40)
for file in files:
    pool.apply_async(readwrite,(file,))

【问题讨论】:

  • 读/写操作通常是任何多线程解决方案的瓶颈,但在您的代码中,它似乎是唯一的操作。在这种情况下,多线程如果不能缩小它,就会将代码变成一个单一的瓶颈。
  • 当你用20个文件试一试并检查修改后的文件是否正确?换句话说,即使 slow,您的解决方案是否会产生正确的输出?
  • 你试过用concurrent.futures.ThreadPoolExecutor吗??
  • 如何确定问题出在 io 操作中?刚刚检查了几个输出,它们看起来是正确的,我没有尝试过 ThreadPoolExecutor

标签: python io threadpool python-multithreading


【解决方案1】:

看docs的例子:

pool.apply_async(f, (20,)) # runs in *only* one process

正如它所说,这样的调用只使用池中的一个进程/线程。

您应该改用pool.map()。示例如下:

from multiprocessing import Pool

def readwrite(filename):
    pass
    # Your code here

if __name__ == '__main__':
    with Pool(5) as p:
        results = p.map(readwrite, filenames)

【讨论】:

  • 只是为了确定你的意思是 apply_async 每次只使用池中的同一个线程吗?
  • 可能不会,但我认为,使用 apply_async 而不使用 .get() 可能会在 40 次调用后阻塞池,map() 应该可以解决这个问题
【解决方案2】:

你不能那样做,如果你有超过 10,000 个文件,这意味着可能有超过 10,000 个线程,这对于普通计算机来说单核处理太多了,如果你最好一个一个地检查它们重新使用线程,你可以计算它需要的时间,并跟踪你重写了多少文件,处理能力和计算能力是什么。如果您的 CPU 上有多个内核,您可以尝试使用 multiprocessing 模块将其最大化 "The “multi” in multiprocessing refers to the multiple cores in a computer's central processing unit (CPU)" ,通常是 2 或 4 个核心,您可以像下面的示例中的 How to use multiprocessing pool.map with multiple arguments

def multi_run_wrapper(args):
   return add(*args)

def add(x,y):
    return x+y

if __name__ == "__main__":
    from multiprocessing import Pool
    pool = Pool(4)
    results = pool.map(multi_run_wrapper,[(1,2),(2,3),(3,4)])
    print results

【讨论】:

  • pool = ThreadPool(40) 不是说最大线程数是 40?我正在使用 apply_async 因为我没有它们在不同文件夹中的所有文件的列表我使用 os.walk 获取所有文件我可以将它们添加到列表中然后使用 pool.map(func,files)但为什么呢?
  • 线程池意味着您在同一个核心上最多打开 40 个线程。 Thread - multi programs on the same processorMultiprocess - using another processor at the same time
猜你喜欢
  • 2015-11-21
  • 2019-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多