Roscagem em Python. Como é que Fecho um fio?
Estou a tentar entender o básico de rosca e concorrência. Eu quero um caso simples onde duas threads repetidamente tentar acessar um recurso compartilhado.
o código:
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 __name__ == '__main__':
main()
Então, tenho dois fios, ambos a tentar aumentar o contador. Eu pensei que se o tópico' A 'chamado incre()
, o lock
seria estabelecido, impedindo' B 'de acessar até' A ' ter liberado.
A execução deixa claro que não é esse o caso. Você obtém todos os dados aleatórios incrementos mais ou menos race.
Como é que exactamente é usado o objecto de bloqueio?
Edite, adicionalmente, eu tentei colocar as fechaduras dentro das funções de thread, mas ainda não tive sorte.
46
Author: Eric Leschinski, 2012-05-10
1 answers
Você pode ver que suas fechaduras estão funcionando como você está usando-os, se você desacelerar o processo e fazê-los bloquear um pouco mais. Tiveste a ideia certa, onde rodeaste partes críticas de código com a fechadura. Aqui está um pequeno ajuste ao seu exemplo para mostrar como cada um espera no outro para liberar o bloqueio.
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 __name__ == '__main__':
main()
Saída da amostra:
...
Inside hello_there()
Acquiring lock
Lock Acquired
Inside bye()
Acquiring lock
Lock Acquired
...
56
Author: jdi, 2012-05-09 23:11:36