2010-09-01 6 views
3
>>> l = Lock() 
>>> l.acquire() 
True 
>>> l.release() 
>>> l.release() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: semaphore or lock released too many times 

déclenche une exception ValueError. Comment puis-je empêcher de relâcher une serrure plus d'une fois? Quelque chose comme l.is_released()?Comment savoir si un multiprocessing.Lock Python est publié ou non?

+1

Normalement, vous écririez simplement votre code pour qu'il n'essaie pas de libérer un verrou plus de fois qu'il n'est acquis ... – Amber

+0

Cela pourrait inclure l'utilisation d'un drapeau is_the_lock_locked? –

Répondre

6

La question est un peu floue. Vous devez soit utiliser des sémaphores au lieu de verrous ou vérifier si le verrou est verrouillé.

Les verrous Python ne sont pas identiques aux verrous sur .Net, par exemple. Le verrou de Python déverrouille une fois tous les autres threads acquis() sur le même verrou et bloqués pour le moment. Tout fil peut se libérer et tous vont en même temps. Ainsi, au lieu de faire deuxième relase, faire

if l.locked(): 
    l.release() 

Si vous voulez le comportement « de la file d'attente », où une seule bande de roulement sera propriétaire d'une serrure une fois d'autres versions, utilisez Sémaphore, événement ou d'une autre classe similaire qui permet comportement de verrouillage et de mise en file d'attente imbriqué. Il est intéressant de noter que d'autres langages/loolkits, comme .Net, verrouillent nativement la mise en file d'attente, où les threads peuvent empiler lock.acquire dans l'ordre, bloquer et s'approprier l'objet lock dans l'ordre de la file d'acquisition, non relâchez tout à la fois.

(Edit: oublié de mettre les parents comme dans "si l.locked: l.realse()". Corrigé le code Lock.locked est confirmé comme étant une méthode présente dans cPython 2.6.x, 3.x, IronPython 2.6.1)

+7

>>> de multitraitement importation de verrouillage >>> Lock() verrouillé retraçage (appel le plus récent en dernier): Fichier "", ligne 1, dans AttributeError: objet 'Lock' n'a pas d'attribut 'verrouillé' –

+1

Vous pouvez faire un acquisition non bloquante comme dans "not lock.acquire (False)" en vérifiant le code retour. – kristopolous

6

L'attente est que le contexte qui a acquis le verrou doit être conscient du moment où il devrait le libérer. Dans quelle circonstance essaieriez-vous de le relâcher plusieurs fois?

+0

Dites le thread a acquis le verrou, mais tout en faisant le travail il y a une exception, j'ai essayé sauf le bloc, donc je veux vérifier quand l'exception se produit le verrou a été acquis ou non pour éviter les interblocages. –

+2

Faites votre essai plus granulaire ou profitez des gestionnaires de contextes (avec my_lock :) pour garantir la libération de votre verrou. . –

0

Depuis lock.acquire() renvoie true si le verrou est correctement acquis, vous pouvez stocker l'état de verrouillage dans une variable locale, puis encapsuler lock.acquire() et le code suivant dans un essai -finalement bloquer. Ensuite, dans le bloc finally, vous pouvez interroger la variable pour voir si le verrou a été acquis ou non. Si c'est le cas, relâchez.

Questions connexes