我有一个Python应用程序可以执行以下操作:
- 每 2-3 分钟由另一个进程调用一次,以便使用
with shelve.open(shelvefilename, flag='c')
存储对象。 - 每分钟由另一个进程调用多次,以便使用
with shelve.open(shelvefilename, flag='r')
读取该搁置文件
问题是有时我收到_gdbm.error: [Errno 11] Resource temporarily unavailable
错误:
File "/path/to/myprog.py", line 755, in mymethod
with shelve.open(shelvefilename, flag='r') as shlvfile:
File "/usr/local/lib/python3.6/shelve.py", line 243, in open
return DbfilenameShelf(filename, flag, protocol, writeback)
File "/usr/local/lib/python3.6/shelve.py", line 227, in __init__
Shelf.__init__(self, dbm.open(filename, flag), protocol, writeback)
File "/usr/local/lib/python3.6/dbm/__init__.py", line 94, in open
return mod.open(file, flag, mode)
_gdbm.error: [Errno 11] Resource temporarily unavailable
我的猜测是发生这种情况是因为在某个时候我已经打开了搁置文件进行读取和写入操作,这在定义上是有问题的。
有什么方法可以在不干扰读取操作的情况下更新搁架文件?
我刚刚在一个小模块中使用搁置来缓存汇率时遇到了这个问题。您可以使用 python 线程和全局threading.Lock()
对象来解决此问题。
from threading import Lock
import shelve
mutex = Lock()
mutex.acquire()
db = shelve.open(db_name)
# write to db
db.close()
mutex.release()
代码片段的原始来源和想法的功劳可以找到@http://georg.io/2014/06/Python-Shelve-Thread-Safety
"线程。Lock(('' 对象通过阻止其他 python 线程来工作,直到它被释放。见 https://docs.python.org/2/library/threading.html#lock-objects
这更像是一个概念问题。如果一个进程修改文件中的数据,而另一个进程同时读取数据,则结果是不可预测的。
假设您读取了文件的一部分,此时只写入了某个值的一半。读取根本无法正确解析条目,也可能无法解析所有后续条目。换句话说,它迟早会破裂。
我认为最好的方法是将"搁置"集中在单个进程中或使用数据库。