Se basa en la answer por el usuario zgoda. Principalmente aborda una complicada preocupación que tiene que ver con el acceso de escritura al archivo de bloqueo. En particular, si el archivo de bloqueo se creó primero por root
, otro usuario foo
no podrá intentar reescribir este archivo debido a la ausencia de permisos de escritura para el usuario foo
. La solución obvia parece ser crear el archivo con permisos de escritura para todos. Esta solución también se basa en un answer diferente por mí, teniendo que hacer la creación de un archivo con dichos permisos personalizados. Esta preocupación es importante en el mundo real donde su programa puede ser ejecutado por cualquier usuario, incluido root
.
import fcntl, os, stat, tempfile
app_name = 'myapp' # <-- Customize this value
# Establish lock file settings
lf_name = '.{}.lock'.format(app_name)
lf_path = os.path.join(tempfile.gettempdir(), lf_name)
lf_flags = os.O_WRONLY | os.O_CREAT
lf_mode = stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH # This is 0o222, i.e. 146
# Create lock file
# Regarding umask, see https://stackoverflow.com/a/15015748/832230
umask_original = os.umask(0)
try:
lf_fd = os.open(lf_path, lf_flags, lf_mode)
finally:
os.umask(umask_original)
# Try locking the file
try:
fcntl.lockf(lf_fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
except IOError:
msg = ('Error: {} may already be running. Only one instance of it '
'can run at a time.'
).format('appname')
exit(msg)
Una limitación del código anterior es que si el archivo de bloqueo ya existía con permisos inesperados, no serán corregidos esos permisos.
Me hubiera gustado usar /var/run/<appname>/
como el directorio para el archivo de bloqueo, pero crear este directorio requiere root
permisos. Puede tomar su propia decisión sobre qué directorio usar.
Tenga en cuenta que no es necesario abrir un identificador de archivo para el archivo de bloqueo.
Por convención, esto debería ir bajo/var/run /, ¿correcto? –
Por curiosidad, ¿no simplemente abrir el archivo para acceso exclusivo hace el trabajo de un mutex? – Menkboy
Menkboy, si el archivo se cierra correctamente en caso de un bloqueo, entonces creo que funcionará perfectamente y simplificará aún más las cosas. Gracias. –