[英]Python Multithreading issue file manipulation
我一直在嘗試擺脫Python中多線程的困擾。 但是,每當我嘗試使其做一些有用的事情時,都會遇到問題。
在這種情況下,我有300個PDF文件。 為簡單起見,我們假設每個PDF都只有一個唯一的編號(例如1到300)。 我試圖使Python打開文件,從中獲取文本,然后使用該文本相應地重命名文件。
我制作的非多線程版本效果驚人。 但這有點慢,我想我是否可以加快速度。 但是,此版本找到第一個文件,正確地重命名它,然后引發錯誤:
FileNotFoundError: [Errno 2] No such file or directory: './pdfPages/1006941.pdf'
它基本上是在告訴我它找不到該名稱的文件。 之所以不能,是因為它已經命名了。 在我的腦海中,這告訴我,我大概已經弄亂了這個循環和/或多線程。
任何幫助,將不勝感激。
資源:
import PyPDF2
import os
from os import listdir
from os.path import isfile, join
from PyPDF2 import PdfFileWriter, PdfFileReader
from multiprocessing.dummy import Pool as ThreadPool
# Global
i=0
def readPDF(allFiles):
print(allFiles)
global i
while i < l:
i+=1
pdf_file = open(path+allFiles, 'rb')
read_pdf = PyPDF2.PdfFileReader(pdf_file)
number_of_pages = read_pdf.getNumPages()
page = read_pdf.getPage(0)
page_content = page.extractText()
pdf_file.close()
Text = str(page_content.encode('utf-8')).strip("b").strip("'")
os.rename(path+allFiles,path+pre+"-"+Text+".PDF")
pre = "77"
path = "./pdfPages/"
included_extensions = ['pdf','PDF']
allFiles = [f for f in listdir(path) if any(f.endswith(ext) for ext in included_extensions)] # Get all files in current directory
l = len(allFiles)
pool = ThreadPool(4)
doThings = pool.map(readPDF, allFiles)
pool.close()
pool.join()
是的,事實上,您已經說錯了。 循環根本不應該在那里。 它由pool.map(...)
隱式處理,以確保每個函數調用都將從您的列表中接收一個唯一的文件名以供使用。 您不應執行任何其他循環。
我通過刪除循環和其他一些更改(以下是我認為是次要的但仍是改進的)來更新您的代碼:
# Removed a number of imports
import PyPDF2
import os
from multiprocessing.dummy import Pool as ThreadPool
# Removed not needed global variable
def readPDF(allFiles):
# The while loop not needed, as pool.map will distribute the different
# files to different processes anyway
print(allFiles)
pdf_file = open(path+allFiles, 'rb')
read_pdf = PyPDF2.PdfFileReader(pdf_file)
number_of_pages = read_pdf.getNumPages()
page = read_pdf.getPage(0)
page_content = page.extractText()
pdf_file.close()
Text = str(page_content.encode('utf-8')).strip("b").strip("'")
os.rename(path+allFiles,path+pre+"-"+Text+".PDF")
pre = "77"
path = "./pdfPages/"
included_extensions = ('pdf','PDF') # Tuple instead of list
# Tuple allows for simpler "F.endswith"
allFiles = [f for f in os.listdir(path) if f.endswith(included_ext)]
pool = ThreadPool(4)
doThings = pool.map(readPDF, allFiles)
# doThings will be a list of "None"s since the readPDF returns nothing
pool.close()
pool.join()
因此,不需要全局變量和計數器,因為所有這些都是隱式處理的。 但是,即使進行了這些更改,也無法完全確定這將大大加快執行速度。 最有可能的是,程序執行的大部分時間都在等待磁盤加載。 在這種情況下,即使您有多個線程,也有可能它們仍必須等待主資源(即硬盤驅動器)。 但是要確定,您必須進行測試。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.