¿Tiene el módulo de estantería Python alguna protección incorporada para garantizar que dos procesos no estén escribiendo en un archivo al mismo tiempo?Módulo de estantería Python pregunta
Respuesta
El módulo shelve utiliza un paquete de base de datos subyacente (como dbm, gdbm o bsddb).
El restrictions pragraph dice (el subrayado es mío):
El módulo de estantería no admite simultáneas de lectura/escritura a los objetos dejados de lado. (Múltiples accesos simultáneos de lectura son seguros.) Cuando un programa tiene un estante abierto para escribir, ningún otro programa debe tenerlo abierto para lectura o escritura. El bloqueo de archivos Unix se puede usar para resolver esto, pero esto difiere en las versiones de Unix y requiere conocimiento sobre la implementación de la base de datos utilizada.
Conclusión: depende del sistema operativo y de la base de datos subyacente. Para mantener las cosas portátiles, no construya sobre concurrencia.
Según la respuesta superior, no es seguro tener múltiples escritores en la estantería. Mi enfoque para hacer que los estantes sean más seguros es escribir un envoltorio que se encargue de abrir y acceder a los elementos del estante. El código de contenedor es como la siguiente:
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()
he implementado Ivo's approach como un gestor de contexto, para cualquier persona interesada:
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
- 1. Operador de módulo Perl pregunta
- 2. Estantería vs Espacios de trabajo en TFS
- 3. Newbie Python Pregunta sobre tuplas
- 4. python "módulo de cadena"?
- 5. sl4a python notificar pregunta
- 6. Python Threading Concept Pregunta
- 7. Web Python Pregunta
- 8. Python cliente/servidor pregunta
- 9. Python establecer pregunta intersección
- 10. Python pregunta re.sub
- 11. python csv pregunta
- 12. diseño de módulo de python
- 13. Módulo Python MySQL
- 14. módulo dinámico en Python
- 15. módulo python para nslookup
- 16. Módulo SSH para python
- 17. Dependencia del módulo Python
- 18. Python: La importación de módulo
- 19. Operador de módulo en Python
- 20. Python cruzada módulo de registro
- 21. Desarrollo del módulo de Python
- 22. dinámicamente importar módulo de Python
- 23. Orden de inicialización del módulo de Python?
- 24. descargar un módulo en Python
- 25. Python para la pregunta de bucle
- 26. Pregunta matemática respecto uuid4 de Python
- 27. Una pregunta trivial de error de SWIG de Python
- 28. Python Clase vs. Módulo Atributos
- 29. ImportError: Sin módulo denominado - Python
- 30. Módulo Python OCR en Linux?
por cierto pensé en la restricción de la comparación y de intercambio arriba- específica nivel de teclas, pero no estoy seguro de si la actualización de una clave puede no sobrescribir todas las demás y también puede depender de la base de datos subyacente, por lo tanto, mejor bloquear todo y estar a salvo –