質問
Pythonがモジュールを棚上げしてい任意の保護は、2つのプロセスが同時にファイルへの書き込みをされていないことを確認することで構築しています!
解決
棚モジュールは、基礎となるデータベースのパッケージ(例えば、DBM、 GDBM <として使用します/>又ははbsddb)。
(私の言うの棚上げモジュールの を棚上げオブジェクトへの同時読み取り/書き込みアクセスをサポートしていません。 (複数の同時読み取りアクセスが安全である。)プログラムは、書き込み用にオープンシェルフを持っている場合は、他のプログラムは、それが読み取りまたは書き込みのためにオープンしていないはずです。 Unixのファイルのロックは、これを解決するために使用することができるが、これはUnixのバージョン間で異なり、使用するデータベースの実装についての知識が必要になります。
結論:それはOSと基礎となるDBに依存します。ポータブル物事を保つために、同時実行の上に構築されません。
他のヒント
トップの答えを1として、それは棚上げに複数のライターを持ってしても安全ではありません。棚は、より安全な作りに私のアプローチは、開口部の世話をするラッパーを書いて、アクセスする要素を棚上げすることです。ラッパーのコードは次のようになります。
def open(self, mode=READONLY):
if mode is READWRITE:
lockfilemode = "a"
lockmode = LOCK_EX
shelve_mode = 'c'
else:
lockfilemode = "r"
lockmode = LOCK_SH
shelve_mode = 'r'
self.lockfd = open(shelvefile+".lck", lockfilemode)
fcntl.flock(self.lockfd.fileno(), lockmode | LOCK_NB)
self.shelve = shelve.open(shelvefile, flag=shelve_mode, protocol=pickle.HIGHEST_PROTOCOL))
def close(self):
self.shelve.close()
fcntl.flock(self.lockfd.fileno(), LOCK_UN)
lockfd.close()
from contextlib import contextmanager, closing
from fcntl import flock, LOCK_SH, LOCK_EX, LOCK_UN
import shelve
@contextmanager
def locking(lock_path, lock_mode):
with open(lock_path, 'w') as lock:
flock(lock.fileno(), lock_mode) # block until lock is acquired
try:
yield
finally:
flock(lock.fileno(), LOCK_UN) # release
class DBManager(object):
def __init__(self, db_path):
self.db_path = db_path
def read(self):
with locking("%s.lock" % self.db_path, LOCK_SH):
with closing(shelve.open(self.db_path, "c", 2)) as db:
return dict(db)
def cas(self, old_db, new_db):
with locking("%s.lock" % self.db_path, LOCK_EX):
with closing(shelve.open(self.db_path, "c", 2)) as db:
if old_db != dict(db):
return False
db.clear()
db.update(new_db)
return True
所属していません StackOverflow