2012-04-21 133 views
3

我有一個服務器上運行的幾個腳本,醃製和unpickle各種字典。他們都使用相同的基本代碼進行酸洗,如下所示:Python酸洗字典EOFError

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

您是否在使用任何形式的鎖定策略? – 2012-04-21 22:31:30

+0

我沒有使用任何鎖定策略... – jordanskis 2012-04-21 22:34:49

回答

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 

最後,一些讀進程將試圖讀取醃文件而寫入過程已經開放寫入。您需要確保您有一些方法可以告訴另一個進程在嘗試讀取文件之前是否已經打開了一個文件。

對於一個非常簡單的解決方案,看看this thread that discusses using Filelock

+2

AJ,我感謝您的回答。但是,只有一個程序使用每個字典。因此,從來沒有另一個進程嘗試讀取或打開當前進程正在使用或寫入的字典。 – jordanskis 2012-04-21 23:12:35

+1

你可以在你的問題中包含完整的回溯? – 2012-04-21 23:13:31

+0

我已經用回溯更新了原始問題。謝謝你的幫助! – jordanskis 2012-04-21 23:24:24

5

所以這實際上證明是一個內存問題。當計算機耗盡內存並嘗試取消或加載數據時,該進程將無法聲明此EOFError。我增加了計算機上的內存,這再次成爲問題。

感謝您的所有意見和幫助。

+2

平均來說,你在酸洗和取出的字典有多大? – Algorithmatic 2014-11-05 06:28:36