gpt4 book ai didi

python - 为什么我的脚本在删除数百万个文件时会定期卡住?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:29:46 25 4
gpt4 key购买 nike

我的目标是从 dir 中删除 1000 万个临时文件。因此,我尝试编写一个 Python 脚本来执行此操作。第一个场景看起来像 that :

#!/usr/bin/python

import os,sys
dirname = os.getcwd() if len(sys.argv) == 1 else sys.argv[1]
deleteConfirm = raw_input('Delete all files from dir ' + str(dirname) + ' (y/n)? ')
if(deleteConfirm not in ['y','Y']):
os._exit(0)

counter = 0
flist = os.listdir(dirname)
for file in flist:
os.remove(os.path.join(dirname, file))
counter+=1
if(0==counter%1000):
sys.stdout.write('\rDeleted %d files' % counter)
sys.stdout.flush()

print '\nDeleted %d files' % counter

此代码有效,但我发现它每 10-15 秒停止一次,并且在几分钟左右不工作。例如,前几秒场景快速输出已删除文件的数量——它仅在 3-5 秒内删除了 28000 个文件,但随后它的输出停止在“已删除 28000 个文件”并等待很长时间——大约一分钟左右。然后输出再次快速更新,并在几秒钟内再次删除数千个文件。但随后它再次停止并等待某些东西。我认为这是由于锁定的文件,所以我尝试编写新的场景,使用 python3 和多处理模块,在几个进程中删除文件。我认为这可能会有所帮助,因为即使一个进程等待某个文件解锁,其他进程也会完成他们的工作。

Here是新脚本:

#!/usr/bin/python3

import os, sys, time
from multiprocessing import Pool
dirname = os.getcwd() if len(sys.argv) == 1 else sys.argv[1]
procNum = 5 if len(sys.argv) < 3 else sys.argv[2]
deleteConfirm = input('Delete all files from dir ' + str(dirname) + ' (y/n)? ')
if(deleteConfirm not in ['y','Y']):
sys.exit()

def main():
flist = os.listdir(dirname)
count = len(flist)
if count < 100000:
counter = 0
for file in flist:
os.remove(os.path.join(dirname, file))
counter+=1
if(0==counter%1000):
sys.stdout.write('\rDeleted %d files' % counter)
sys.stdout.flush()
print('\rDeleted %d files' % counter)
sys.exit(0)
else:
workers = Pool(processes=procNum)
result = workers.imap_unordered(delfile,flist)
workers.close()
while True:
time.sleep(5)
completed = result._index
if completed == count:
print('')
break
sys.stdout.write('\rRemoved %d files' % result._index)
workers.join()

def delfile(fname):
os.remove(os.path.join(dirname,fname))

我尝试了这个新脚本,但它每隔几秒就会停止一次,就像以前的情况一样。我想不通,为什么会这样。有什么想法吗?

最佳答案

假设您使用的是 Linux(其他操作系统可能不同),详情在 Linux 文档中:参见示例 https://www.kernel.org/doc/Documentation/sysctl/vm.txt .

Linux 通过创建“脏页”来处理磁盘写入,“脏页”是等待物理复制到磁盘的内存部分。物理副本稍后出现。这就是为什么 os.remove() 通常非常快:它只会在内存中创建或修改一个页面,并留下物理副本供以后使用。 (如果很快,我们执行另一个需要更改同一内存页的 os.remove(),那么我们就赢了:不需要将此页多次写入磁盘。)

通常,称为“pdflush”的守护进程会定期唤醒以执行此写入磁盘操作。但是如果一个进程真的产生了很多脏页,那么内核会在某一时刻停止它(在随机的 os.remove() 调用中)并强制写入磁盘现在,对于部分待处理页面。它只允许程序在脏页再次低于合理阈值时继续。很可能,“pdflush”将立即继续编写其余部分。显然,如果你的程序继续产生脏页,它将再次达到上限并再次暂停。

这就是导致流程暂停的原因。这是内核工作方式的副作用。你可以忽略它:物理上,磁盘一直很忙。

关于python - 为什么我的脚本在删除数百万个文件时会定期卡住?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16722112/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com