Exemple 2 de compartició de memòria¶
El fitxer comptadorSZC.py crea 2 fils de control que usen la variable compartida n. Un fil incrementa 10000 vegades la variable n. L’altre fil la decrementa 10000 vegades. Amb el valor inicial 0, el resultat de:py:obj:n al final de l’execució dels fils, n ha de valer 0. Comproveue que això no és així i el resultat és incert.
Amb el fitxer comptadorAZC.py s’ha protegit la operació d’increment o decrement com a zona crítica. El resultat sempre serà zero. Aquí és on es pot veure l’increment o decrement no és atòmic.
Comptador sense pany (lock)¶
Fitxer comptadorSZC.py
import threading
n=0
nVegades=1000000
def fil1():
global n
for i in range(nVegades):
n = n + 1
def fil2():
global n
for i in range(nVegades):
n = n - 1
def principal():
t1= threading.Thread(target=fil1)
t2= threading.Thread(target=fil2)
t1.start()
t2.start()
t1.join()
t2.join()
print(n)
if __name__=="__main__":
principal()
Comptador amb pany (lock)¶
Fitxer comptadorAZC.py
import threading
n=0
nVegades=1000000
critic=threading.Lock()
def fil1():
global n
for i in range(nVegades):
critic.acquire()
n = n + 1
critic.release()
def fil2():
global n
for i in range(nVegades):
critic.acquire()
n = n - 1
critic.release()
def principal():
t1= threading.Thread(target=fil1)
t2= threading.Thread(target=fil2)
t1.start()
t2.start()
t1.join()
t2.join()
print(n)
if __name__=="__main__":
principal()
Comptador amb pany (lock) Versió en classes.¶
Fitxer comptadorCAZC.py
import threading
n=0
class ComptaDescompta(threading.Thread):
def __init__(self, nVegades, critic, delta):
super().__init__()
self.nVegades = nVegades
self.critic = critic
self.delta = delta
def run(self):
global n
for i in range(self.nVegades):
self.critic.acquire()
n = n + self.delta
self.critic.release()
def principal():
nVegades=1000000
critic=threading.Lock()
t1= ComptaDescompta(nVegades, critic, 1)
t2= ComptaDescompta(nVegades, critic, -1)
t1.start()
t2.start()
t1.join()
t2.join()
print(n)
if __name__=="__main__":
principal()