Sync Mutex: Lock y Unlock

3/19
Recursos

Aportes 5

Preguntas 2

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

Mientras más aprendo de Go más quedo asombrado del cuidado que tuvieron sus creadores. Se ve que examinaron muchos de los problemas recurrentes de otros lenguajes de programación e implementaron soluciones nativas en el lenguaje.

package main

import "sync"

// Problem: Race condition
// build: go build --race main.go

var (
	balance int = 100
)

func Deposit(amount int, wg *sync.WaitGroup, lock *sync.Mutex) {
	defer wg.Done()
	defer lock.Unlock() // Unlock is a method of the Mutex struct

	lock.Lock() // Lock the mutex
	b := balance
	balance = b + amount
}

func Balance() int {
	b := balance
	return b
}

func main() {
	var wg sync.WaitGroup
	var lock sync.Mutex // Mutex is a struct that implements the Lock and Unlock methods

	for i := 1; i <= 5; i++ {
		wg.Add(1)
		go Deposit(i*100, &wg, &lock)
	}

	wg.Wait()
	println(Balance())
}

Para ver claramente el problema de no bloquear el acceso a la variable compartida:

Si en el for en lugar de 5 pones por ejemplo 5000, la suma total es diferente en cada ejecución, variando incluso por varios millones de un resultado a otro.

Una vez que aplicas el bloqueo, el resultado ya siempre es el mismo.

Voy en el minuto 6:53 y tuve un momento DiCaprio, no pude dejar de pensar en las transacciones de PostgreSQL (cuyo curso tome hace pocos días XD).

Se puede verificar el valor que esperamos de resultado usando la fórmula de Gauss. 1+2+3+…+n=n(n+1)/2.