我在服务器上运行了几个脚本,这些脚本可以挑选和取消各种字典。他们都使用相同的基本代码进行酸洗,如下所示:
SellerDict=open('/home/hostadl/SellerDictkm','rb')
SellerDictionarykm=pickle.load(SellerDict)
SellerDict.close()
SellerDict=open('/home/hostadl/SellerDictkm','wb')
pickle.dump(SellerDictionarykm,SellerDict)
SellerDict.close()
除了其中一个脚本外,所有脚本都运行正常。有问题的那个去各个网站并擦除数据并将其存储在字典中。这段代码运行一整天的酸洗和解毒词典,并在午夜停止。然后一个cronjob再次启动它 第二天早上。此脚本可以运行数周而不会出现问题,但是当脚本尝试打开字典时,由于EOFError而导致脚本每月大约一次。字典的大小通常约为80 MB。我甚至尝试在SellerDict.close()之前添加SellerDict.flush()来挑选数据以确保晚上被刷新。
任何想法都可能导致这种情况? Python非常可靠,所以我不认为这是由于文件的大小。在死亡之前代码运行良好很长时间,这让我相信可能会在字典中保存导致此问题的内容,但我不知道。
另外,如果你知道一种更好的方法来保存除了泡菜之外的字典,我愿意接受选择。就像我之前说的那样,词典不断被打开和关闭。仅仅为了澄清,只有一个程序将使用相同的字典,因此问题不是由几个程序试图访问同一个字典引起的。
更新:
这是我从日志文件中获得的回溯。
Traceback (most recent call last):
File "/home/hostadl/CompileRecentPosts.py", line 782, in <module>
main()
File "/home/hostadl/CompileRecentPosts.py", line 585, in main
SellerDictionarykm=pickle.load(SellerDict)
EOFError
答案 0 :(得分:6)
所以这实际上是一个记忆问题。当计算机耗尽RAM并尝试取消或加载数据时,该过程将无法声明此EOFError。我增加了计算机上的RAM,这再也不是问题了。
感谢所有的评论和帮助。
答案 1 :(得分:2)
以下是您不使用锁定时会发生的情况:
import pickle
# define initial dict
orig_dict={'foo':'one'}
# write dict to file
writedict_file=open('./mydict','wb')
pickle.dump(orig_dict,writedict_file)
writedict_file.close()
# read the dict from file
readdict_file=open('./mydict','rb')
mydict=pickle.load(readdict_file)
readdict_file.close()
# now we have new data to save
new_dict={'foo':'one','bar':'two'}
writedict_file=open('./mydict','wb')
#pickle.dump(orig_dict,writedict_file)
#writedict_file.close()
# but...whoops! before we could save the data
# some other reader tried opening the file
# now they are having a problem
readdict_file=open('./mydict','rb')
mydict=pickle.load(readdict_file) # errors out here
readdict_file.close()
这是输出:
python pickletest.py
Traceback (most recent call last):
File "pickletest.py", line 26, in <module>
mydict=pickle.load(readdict_file) # errors out here
File "/usr/lib/python2.6/pickle.py", line 1370, in load
return Unpickler(file).load()
File "/usr/lib/python2.6/pickle.py", line 858, in load
dispatch[key](self)
File "/usr/lib/python2.6/pickle.py", line 880, in load_eof
raise EOFError
EOFError
最终,一些读取过程将尝试读取pickle文件,而写入过程已经打开写入。在尝试从中读取之前,您需要确保有一些方法可以判断另一个进程是否已打开文件进行写入。
要获得一个非常简单的解决方案,请查看this thread that discusses using Filelock。