我编写了一个基本程序来检查包含许多jpeg文件(500000+)的目录树 确认它们没有损坏(大约有3-5%的文件似乎在某种程度上损坏了),然后取一份文件(即使是损坏的文件)并将信息保存到数据库中。在
有问题的jpeg文件位于windows系统上,并通过cifs装载在linux机器上。它们的大小大多在4兆字节左右,尽管有些可能稍大或稍小。在
当我运行这个程序时,它似乎运行得相当好,然后它就崩溃了,出现了下面的错误。这是在它处理了大约1100个文件之后(错误表明,在试图打开一个4.5 meg的文件时出现了问题)。在
现在我知道我可以捕捉到这个错误并继续或重试等等,但是我很好奇为什么它会首先发生,如果捕捉和重试真的能解决问题-或者它会仅仅停留在重试中(当然,除非我限制了重试,但是会跳过一个文件)。在
我在debian系统上使用“Python2.7.5+”来运行这个。系统至少有4Gig(可能是8)的ram,top报告说,脚本在任何时候运行时使用的ram少于1%,cpu的使用率低于3%。类似地,这个脚本运行的jpeginfo也使用同样少的内存和cpu。在
{我用另一种方法来避免在给定的内存中读取过多的文件
您还可以注意到“jpeginfo”命令在while循环中寻找“[OK]”响应。 这是因为如果“jpeginfo”认为找不到该文件,它将返回0,因此它不会被视为错误状态subprocess.check_输出打电话。在
我想知道jpeginfo在第一次尝试时似乎找不到某些文件这一事实是否有关联(我怀疑是这样),但返回的错误是cannot allocate memory,而不是file not found。在
错误:
Traceback (most recent call last):
File "/home/m3z/jpeg_tester", line 95, in <module>
main()
File "/home/m3z/jpeg_tester", line 32, in __init__
self.recurse(self.args.dir, self.scan)
File "/home/m3z/jpeg_tester", line 87, in recurse
cmd(os.path.join(root, name))
File "/home/m3z/jpeg_tester", line 69, in scan
with open(filepath) as f:
IOError: [Errno 12] Cannot allocate memory: '/path/to/file name.jpg'
完整程序代码:
^{pr2}$
在我看来,Python只是从底层的})。在
open()
调用传递了一个错误,而真正的罪魁祸首是Linux CIFS支持-我怀疑Python会合成ENOMEM
,除非系统内存真的耗尽了(而且可能即使这样,我也希望调用Linux OOM killer,而不是获取{不幸的是,它可能需要一些Linux文件系统专家来弄清楚那里到底发生了什么,但是看看sources for CIFS in the Linux kernel,我可以看到当各种内核特定的资源耗尽而不是系统内存总量时,
ENOMEM
会返回很多地方,但是我对它还不太熟悉,不知道它们有多可能。在要排除特定于Python的任何内容,可以在
strace
下运行该进程,这样就可以看到Python从Linux获得的确切返回代码。为此,请运行以下命令:-f
将跟随子进程(即您运行的jpeginfo
命令),而-eopen
将只显示open()
调用,而不是所有系统调用(默认情况下,strace
就是这样做的)。这可能会生成合理数量的输出,这就是为什么我在上面的示例中将其重定向到一个文件,但是如果您愿意,可以让它显示在您的终端上。在我希望你在得到例外之前会看到这样的情况:
^{pr2}$如果是这样的话,这个错误直接来自于文件系统
open()
调用,而在Python脚本中对此几乎无能为力。如果jpeginfo
失败,您可以捕捉异常并重试(可能在短暂的延迟之后),但是如果不知道首先是什么导致了错误,很难说这个策略会有多成功。在当然,您可以在本地复制这些文件,但这听起来会很痛苦,因为文件太多了。在
编辑:作为旁白,您将看到许多与脚本无关的
open()
调用,因为strace
正在跟踪Python发出的每一个调用,其中包括它打开自己的.py
和.pyc
文件。忽略那些与你感兴趣的文件无关的文件。在相关问题 更多 >
编程相关推荐