问题描述
这个程序返回视频的分辨率,但由于我需要一个大型项目,我需要多处理。我曾尝试使用不同的函数进行并行处理,但这只会多次运行它,并不能提高效率,我正在发布整个代码。你能帮我创建一个包含所有内核的主进程吗。
import os
from tkinter.filedialog import askdirectory
from moviepy.editor import VideoFileClip
if __name__ == "__main__":
dire = askdirectory()
d = dire[:]
print(dire)
death = os.listdir(dire)
print(death)
for i in death: #multiprocess this loop
dire = d
dire += f"/{i}"
v = VideoFileClip(dire)
print(f"{i}: {v.size}")
此代码工作正常,但我需要帮助为单独的 for 循环创建主进程(使用所有内核)。你能原谅我对多处理生气的变量名称吗?此外,如果您有提高代码效率的技巧,我将不胜感激。
解决方法
您是,我想,假设目录中的每个文件都是视频剪辑。我假设处理视频剪辑是一个适合线程的 I/O 绑定“进程”。在这里,我以这种方式随意创建了一个 20 个线程的线程池:
MAX_WORKERS = 20 # never more than this
N_WORKERS = min(MAX_WORKERS,len(death))
在性能下降之前,您必须试验 MAX_WORKERS 的大小。这可能是一个较低的数字,不是因为您的系统不能支持大量线程,而是因为对磁盘上可能分布在介质上的多个文件的并发访问可能效率低下。
import os
from tkinter.filedialog import askdirectory
from moviepy.editor import VideoFileClip
from concurrent.futures import ThreadPoolExecutor as Executor
from functools import partial
def process_video(parent_dir,file):
v = VideoFileClip(f"{parent_dir}/{file}")
print(f"{file}: {v.size}")
if __name__ == "__main__":
dire = askdirectory()
print(dire)
death = os.listdir(dire)
print(death)
worker = partial(process_video,dire)
MAX_WORKERS = 20 # never more than this
N_WORKERS = min(MAX_WORKERS,len(death))
with Executor(max_workers=N_WORKERS) as executor:
results = executor.map(worker,death) # results is a list: [None,None,...]
更新
根据@Reishin,moviepy
导致执行 ffmpeg
可执行文件,从而最终创建一个正在完成工作的进程。所以我们在这里也没有必要使用多处理。