Vamos a ver que opciones tenemos:
[1] Usar como lock un archivo que creamos. Se puede usar la llamada os.open() para crear un archivo en exclusiva. El proceso que lo pueda crear tiene via libre para usar ya el fichero que nos interesa. Hay que tener cuidado con proporcionar los mecanismos para no dejar el lock por ahí.
[2] Usar los mecanismos que nos proporciona el OS para bloquear ficheros. Llamada fcntl.lockf().
A continuación voy a copiar dos scripts que demuestran su uso. Ejecutar en primer lugar uno.py e inmediatamente dos.py en otro terminal.
En estos scripts se hace un open() se bloquea el archivo y despues un close().
Una alternativa seria el tener siempre el open() hecho y simplemente hacer el lockf(). Supongo que esto funcionaría pero no lo he probado.
Ya para acabar, comentar la importancia de hacer el seek() en el segundo script para poder escribir en lugar adecaudo del fichero.
uno.py
import os
import fcntl
import time
#--- Creamos el fichero
h = open("kk.txt","w")
h.write("hello\n")
h.close()
#--- Ahora lo abrimos bloquendolo
h = open("kk.txt","a")
fcntl.lockf(h.fileno(),fcntl.LOCK_EX)
print "Hemos pillado el lock y n os vamos a dormir"
time.sleep(15)
print "escribimos"
h.write("hello\n")
print "Tam: ", h.tell()
#h.flush() -> He procado sin el flush y funciona correctamente,
# pero con el, podría ser mas seguro.
# Adicionalmente está la llamada os.fsync().
# Si queremos mas control en el modo de apertura de los
# ficheros tenemos que usar la llamada os.open().
# Por ejemplo si los queremos crear en exclusiva.
print "Liberamos el lock y cerramos"
fcntl.lockf(h.fileno(),fcntl.LOCK_UN)
h.close()
dos.py
import os
import fcntl
import time
#--- Abrimos
#
# Nota: Si usamos LOCK_NB en lockf al adquirirlo y no podemos,
# nos da un error.
h = open("kk.txt","a")
#fcntl.lockf(h.fileno(),fcntl.LOCK_EX|fcntl.LOCK_NB)
fcntl.lockf(h.fileno(),fcntl.LOCK_EX)
print "Hemos pillado el lock y n os vamos a dormir"
#--- Lo usamos
h.seek(0,2)
print "Tam: ", h.tell()
#--- Cerramos
print "Liberamos el lock y cerramos"
fcntl.lockf(h.fileno(),fcntl.LOCK_UN)
h.close()
No hay comentarios:
Publicar un comentario