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.

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