J'essaie de comprendre les bases du threading et de la concurrence. Je veux un cas simple où deux threads essaient à plusieurs reprises d'accéder à une ressource partagée.
Le code:
import threading
class Thread(threading.Thread):
def __init__(self, t, *args):
threading.Thread.__init__(self, target=t, args=args)
self.start()
count = 0
lock = threading.Lock()
def incre():
global count
lock.acquire()
try:
count += 1
finally:
lock.release()
def bye():
while True:
incre()
def hello_there():
while True:
incre()
def main():
hello = Thread(hello_there)
goodbye = Thread(bye)
while True:
print count
if __== '__main__':
main()
Donc, j'ai deux threads, les deux essayant d'incrémenter le compteur. Je pensais que si le thread 'A' appelé incre()
, le lock
était établi, empêchant ainsi l'accès de B jusqu'à la sortie de 'A'.
En cours d'exécution, il est clair que ce n'est pas le cas. Vous obtenez toutes les incréments aléatoires de données aléatoires.
Comment exactement l'objet verrou est-il utilisé?
Modifier, en outre, j'ai essayé de mettre les verrous à l'intérieur des fonctions du fil, mais toujours pas de chance.
Vous pouvez voir que vos verrous fonctionnent assez bien lorsque vous les utilisez, si vous ralentissez le processus et les bloquez un peu plus. Vous avez eu la bonne idée, en entourant les éléments de code critiques avec le verrou. Voici un petit ajustement de votre exemple pour vous montrer comment chacun attend l'autre pour libérer le verrou.
import threading
import time
import inspect
class Thread(threading.Thread):
def __init__(self, t, *args):
threading.Thread.__init__(self, target=t, args=args)
self.start()
count = 0
lock = threading.Lock()
def incre():
global count
caller = inspect.getouterframes(inspect.currentframe())[1][3]
print "Inside %s()" % caller
print "Acquiring lock"
with lock:
print "Lock Acquired"
count += 1
time.sleep(2)
def bye():
while count < 5:
incre()
def hello_there():
while count < 5:
incre()
def main():
hello = Thread(hello_there)
goodbye = Thread(bye)
if __== '__main__':
main()
Exemple de sortie:
...
Inside hello_there()
Acquiring lock
Lock Acquired
Inside bye()
Acquiring lock
Lock Acquired
...