2012-04-21 4 views
3

У меня есть несколько сценариев, запущенных на сервере, который распевает и разглаживает различные словари. Все они используют один и тот же базовый код для засолки, как показано ниже:Python Pickling Dictionary 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 МБ. Я даже попробовал добавить SellerDict.flush() перед SellerDict.close(), когда травил данные, чтобы убедиться, что вечер был покраснел.

Любая идея может быть причиной этого? Python довольно солидный, поэтому я не думаю, что это связано с размером файла. Там, где код работает отлично в течение долгого времени, прежде чем умереть, это заставляет меня поверить, что, возможно, что-то сохраняется в словаре, который вызывает эту проблему, но я понятия не имею.

Кроме того, если вы знаете, как лучше сохранить словари, кроме рассола, я открыт для вариантов. Как я уже говорил, словари постоянно открываются и закрываются. Просто для пояснения, только одна программа будет использовать один и тот же словарь, чтобы проблема не вызывалась несколькими программами, пытающимися получить доступ к одному и тому же словарю.

UPDATE:

Вот отслеживающий, что у меня есть из файла журнала.

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

Вы используете какую-либо стратегию блокировки? –

+0

Я не использую никаких стратегий блокировки ... – jordanskis

ответ

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

+1

Можете ли вы включить полный ответ в свой вопрос? –

+0

Я обновил исходный вопрос с помощью traceback. Спасибо за вашу помощь! – jordanskis

5

Так что это на самом деле оказалось проблемой памяти. Когда компьютер закончит работу с ОЗУ и попытается раскрыть или загрузить данные, процесс не будет требовать этого EOFError. Я увеличиваю ОЗУ на компьютере, и это никогда не было проблемой снова.

Спасибо за все комментарии и помощь.

+2

Насколько велики, в среднем, словари, которые вы травляете и рассыпаете? – Algorithmatic