web-dev-qa-db-fra.com

Mutex à l'échelle du système en Python sous Linux

Existe-t-il un moyen simple d’avoir un mutex à l’échelle du système dans Python sous Linux? Par "au niveau du système", je veux dire que le mutex sera utilisé par un groupe de Python process; Cela contraste avec un mutex traditionnel, qui est utilisé par un groupe de threads dans le même processus.

EDIT: Je ne suis pas sûr que le paquet multiprocessing de Python soit ce dont j'ai besoin. Par exemple, je peux exécuter ce qui suit dans deux interpréteurs différents:

from multiprocessing import Lock
L = Lock()
L.acquire()

Lorsque j'exécute ces commandes simultanément dans deux interpréteurs distincts, je veux que l'un d'eux se bloque. Au lieu de cela, ni l'un ni l'autre ne se bloque; il semble qu'ils n'acquièrent pas le même mutex.

45
emchristiansen

La réponse Unix "traditionnelle" consiste à utiliser des verrous de fichiers. Vous pouvez utiliser lockf(3) pour verrouiller des sections d'un fichier afin que d'autres processus ne puissent pas le modifier. un abus très courant consiste à utiliser cela comme un mutex entre processus. L'équivalent en python est fcntl.lockf

En règle générale, vous écrivez le PID du processus de verrouillage dans le fichier de verrouillage, de sorte que les blocages dus aux processus en train de mourir pendant le verrouillage soient identifiables et réparables.

Cela vous donne ce que vous voulez, puisque votre verrou se trouve dans un espace de noms global (le système de fichiers) et accessible à tous les processus. Cette approche a également l'avantage que des programmes non Python peuvent participer à votre verrouillage. L'inconvénient est que vous avez besoin d'un endroit pour vivre ce fichier de verrouillage; de plus, certains systèmes de fichiers ne se verrouillent pas correctement, ce qui risque d'exclure silencieusement l'exclusion. Vous en gagnez un peu, vous en perdez un peu.

25
zmccord

La norme POSIX spécifie des sémaphores inter-processus pouvant être utilisés à cette fin. http://linux.die.net/man/7/sem_overview

Le module multiprocessing en Python est basé sur cette API et d'autres. multiprocessing.Lock fournit notamment un "mutex" inter-processus. http://docs.python.org/library/multiprocessing.html#synchronization-between-processes

EDIT pour répondre à la question modifiée:

Dans votre preuve de concept, chaque processus construit une Lock(). Donc, vous avez deux serrures distinctes. C'est pourquoi aucun des processus n'attend. Vous devrez partager le même verrou entre les processus. La section à laquelle je me suis connecté dans la documentation multiprocessing explique comment procéder.

11
wberry

Essayez ilock library:

from ilock import ILock

with ILock('Unique lock name'):
    # The code should be run as a system-wide single instance
    ...
7
Symon

Pour un mutex à l’échelle du système qui permet la synchronisation de processus absolument distincts (c’est-à-dire, pour inclure des processus Linux qui n'appartiennent pas à la même arborescence), utilisez simplement fcntl.flock . Je suppose que l’utilisation d’un fichier mémoire sous le dossier/run/shm de Linux peut accélérer son exécution.

Voir plus ici .

1
Ofer