El bloqueo de archivos no funciona como se esperaba
Pregunta
tengo un Thread
-Clasa de extensión que se supone que solo ejecuta una instancia a la vez (proceso cruzado). Para lograr eso, estoy tratando de usar un bloqueo de archivo. Aquí hay fragmentos de mi código:
class Scanner(Thread):
def __init__(self, path):
Thread.__init__(self)
self.lock_file = open(os.path.join(config.BASEDIR, "scanner.lock"), 'r+')
fcntl.lockf(self.lock_file, fcntl.LOCK_EX | fcntl.LOCK_NB)
# Stuff omitted
def run(self):
logging.info("Starting scan on %s" % self.path)
# More stuff omitted
fcntl.lockf(self.lock_file, fcntl.LOCK_UN)
Estaba esperando el lockf
Llame para lanzar una excepción si un Scanner
El hilo ya se estaba ejecutando y no inicializar el objeto en absoluto. Sin embargo, puedo ver esto en la terminal:
INFO:root:Starting scan on /home/felix/Music
INFO:root:Starting scan on /home/felix/Music
INFO:root:Scan finished
INFO:root:Scan finished
Lo que sugiere que dos Scanner
Los hilos se ejecutan al mismo tiempo, sin excepción. Estoy seguro de que me estoy perdiendo algo realmente básico aquí, pero parece que no puedo descubrir qué es eso. ¿Alguien puede ayudar?
Solución
Encontré la solución yo mismo al final. Era para usar fcntl.flock()
en vez de fcntl.lockf()
, con exactamente los mismos parámetros. No estoy seguro de por qué eso marcó la diferencia.
Otros consejos
Estás abriendo el archivo de bloqueo usando r+
que está borrando el archivo anterior y crear uno nuevo. Cada hilo está bloqueando un archivo diferente.
Usar w
o r+a
Junto con el uso de Flock, también tuve que abrir el archivo como así:
fd = os.open(lockfile, os.O_CREAT | os.O_TRUNC | os.O_WRONLY)
No funciona de otro tipo.