Bonjour wiztricks,
Et tu trouves ça plus SIMPLE ?
Désolé, mais au bout de 2 heures, ça ne marche toujours pas... Je ne dois pas être doué.
Je reprendrai un de ces jours.
Une question cependant: quand la 1ère instance du programme se plante pour une raison quelconque, est-ce que le verrou disparait ou pas? S'il reste, c'est un grave défaut, parce que ça veut dire qu'une 1ère instance ne peut plus être lancée de nouveau. Et ce serait encore pire si le verrou restait après reboot...
Tyrtamos
Bonjour,
si ça fonctionne très bien fcntl, soit en attente de la libération du verrou soit en générant une exception.
il est aussi possible d'écrire des infos dans le fichier verrou pour savoir par exemple quel processus l'a créé et depuis quand.
non le verrou ne reste pas si le processus est tué.
Bonjour,
Comme je suis en même temps curieux et têtu, je m'y suis remis, et j'ai réussi!
Je suis reparti sur une page blanche, simplement avec la doc et 2 heures de plus.
Voilà le module portalocker revu à ma sauce:
Et voilà un programme test qui utilise ce module:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 #!/usr/bin/python # -*- coding: utf-8 -*- # Python v2.7 import sys ############################################################################# def lockfile_unix(f): """Unix: verrouille le fichier dont le descripteur est f """ lockf(f.fileno(), LOCK_EX | LOCK_NB) ############################################################################# def lockfile_win(f): """Windows: verrouille le fichier dont le descripteur est f """ locking(f.fileno(), LK_NBLCK, 1) ############################################################################# def lockfile_rien(f): """Ni Windows ni Unix: cette fonction ne fait rien """ pass ############################################################################# lockfile = None # si Unix try: from fcntl import lockf, LOCK_NB, LOCK_EX lockfile = lockfile_unix except: pass # si Windows: if lockfile == None: try: from msvcrt import locking, LK_NBLCK, LK_UNLCK lockfile = lockfile_win except: pass # si aucune des 2 importations ne marche: if lockfile == None: lockfile = lockfile_rien
J'ai vérifié que ça marchait sans modification sous Windows (7) et sous Linux (Ubuntu 10.10): lancement avec 2 consoles.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 #!/usr/bin/python # -*- coding: utf-8 -*- import os, sys import time from portalocker import lockfile ############################################################################# def bidon(): """programme qui ne fait rien d'autre que d'attendre 15 secondes de CPU""" t0 = time.clock() while True: if time.clock()-t0 > 15: break ############################################################################# if __name__ == '__main__': # tentative de verrou sur le fichier témoin (mettre le bon chemin) nfc = "fichierverrou.txt" f = None try: f = open(nfc, 'w') lockfile(f) except: if f != None: f.close() print u"Echec: il y a déjà une 1ère instance en cours!" sys.exit() bidon() f.close() # le fichier témoin doit rester ouvert jusqu'à la fin du programme
J'ai vérifié aussi qu'une fois la 1ère instance du programme terminé, même de façon anormale, le verrou n'est pas maintenu, ce que confirme beekeep (merci).
Il s'agit donc d'une solution qui marche, même si elle n'est pas très simple, et qui a l'avantage de pouvoir être utilisée pour des programmes en console.
Merci, wiztricks!
Tyrtamos
Le verrou est rendu par l'OS lorsqu'il nettoie le process qui a été tué.J'ai vérifié aussi qu'une fois la 1ère instance du programme terminé, même de façon anormale, le verrou n'est pas maintenu, ce que confirme beekeep (merci).
On a potentiellement les mêmes problèmes dans toutes les solutions: si le process est 'bloqué', il faut forcer la sortie et si l'OS est chargé, la libération du lock prendra du temps (de l'ordre de plusieurs dixièmes de secondes).
- W
Partager