¿Cómo bloquear un directorio entre procesos python en linux?

Tengo dos (o más) procesos de Python en ejecución y quiero crear un concepto similar a un exclusión mutua para un recurso compartido. El ‘recurso compartido’ en este caso es un directorio. ¿Cómo puedo implementar un mutex de la manera más fácil / estándar / etc? ¿Un archivo .lock oculto que cada proceso acepta verificar y, si existe, agrega su PID como una nueva fila y luego muestra su PID cuando tienen acceso al archivo?

Básicamente, solo quiero borrar un directorio y asegurarme de que ningún otro proceso intente leerlo o escribir en él mientras lo borro.

¿Hay una forma estándar de Linux de hacer esto? ¿Tal vez algo que pueda ejecutar con una línea de shell de python?

Linux

Hay dos tipos estándar de locking en Linux: locking de asesoría (especificado en POSIX) y locking obligatorio (específico de Linux).

Sin embargo, ambos pueden aplicarse solo en archivos, pero no en directorios. Así que sí, necesitas un archivo de locking. Se supone que todos los usuarios deben conocer el archivo de locking y adquirir el locking antes de acceder al directorio. Por lo tanto, el locking obligatorio no ayudará aquí, y necesita un locking de asesoría.

Hay tres tipos de lockings de archivos de consulta en Linux:

  • flock(2) (especificado en POSIX);
  • Bloqueos de registro POSIX, consulte la sección “Bloqueo de registro consultivo” en fcntl(2) y también la lockf(3) (ambas especificadas en POSIX);
  • Abra los lockings de descripción de archivos, vea fcntl(2) (específico de Linux, disponible en kernels recientes).

Pitón

En Python, las funciones flock() , lockf() y fcntl() están disponibles a través del módulo fcntl . También hay un módulo de flock que agrega compatibilidad con el administrador de contexto a la función fcntl.flock .

Aquí hay un ejemplo:

 import flock with open('/my/dir/lockfile', 'w') as fp: with flock.Flock(fp, flock.LOCK_EX) as lock: pass # exclusive lock is acquired here 

PD.

Con este enfoque, no puede evitar que un proceso aleatorio acceda a su directorio, si no conoce su archivo de locking. Probablemente sea posible implementar un sistema de archivos utilizando FUSE que admita lockings de directorio obligatorios, pero no estoy al tanto de tales implementaciones.

Puede aplicar un locking de rebaño en un directorio. Este es un aviso (no detendrá los procesos que no se preocupan por el locking que toca el directorio). El locking persistirá hasta que su progtwig termine. El código es bastante trivial.

 lockfd = os.open('.',os.O_RDONLY) fcntl.flock(lockfd,fcntl.LOCK_EX | fcntl.LOCK_NB) 

Si mi comprensión de la página de manual es correcta, puedes desbloquearla simplemente haciendo.

 os.close(lockfd) 

Pero no he probado esto, ya que en mi aplicación se desea que el locking persista durante toda la ejecución de los scripts.