https://github.com/yugendev/go-race-condition
Una cuenta bancaria que tiene un balance el cual es accedido por varias funciones de manera concurrente
https://github.com/yugendev/go-race-condition
Last synced: 10 months ago
JSON representation
Una cuenta bancaria que tiene un balance el cual es accedido por varias funciones de manera concurrente
- Host: GitHub
- URL: https://github.com/yugendev/go-race-condition
- Owner: YugenDev
- Created: 2024-06-20T19:26:28.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-06-20T20:53:18.000Z (about 2 years ago)
- Last Synced: 2025-06-15T02:09:08.387Z (about 1 year ago)
- Language: Nix
- Homepage:
- Size: 1.57 MB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
## Condición de Carrera y Solución con `sync.Mutex` en Go
### Problema de Condición de Carrera
En programación concurrente, una condición de carrera (race condition) ocurre cuando varias goroutines acceden y modifican simultáneamente una variable compartida sin la sincronización adecuada. Esto puede llevar a resultados inesperados e incorrectos.
**Escenario de Ejemplo:**
Imaginemos una cuenta bancaria con un saldo almacenado en la variable `balance`. Si dos goroutines (representando depósitos) intentan agregar dinero al saldo al mismo tiempo, podrían surgir problemas:
- **Lecturas Inconsistentes:** Una goroutine podría leer el saldo actual (`b = balance`) antes de que la otra lo actualice. Luego, ambas goroutines agregan sus depósitos al valor `b` desactualizado, lo que resulta en un saldo final incorrecto.
- **Actualizaciones Perdidas:** Si una goroutine incrementa `balance` mientras otra está leyendo su valor, la lectura podría perder la actualización, lo que resultaría en un saldo final incorrecto.
### Solución con `sync.Mutex`
El código Go proporcionado previene efectivamente las condiciones de carrera utilizando un bloqueo `sync.RWMutex`. Veamos cómo funciona:
#### Inicialización de Mutex
```go
var lock sync.RWMutex
```
#### Función `Depositar`
```go
func Depositar(amount int, wg *sync.WaitGroup, lock *sync.RWMutex) {
defer wg.Done()
lock.Lock()
b := balance
balance = b + amount
lock.Unlock()
}
```
- `lock.Lock()`: Antes de acceder a la variable compartida `balance`, llamamos a la función lock de la libreria RWmutex, la gorutine lee esto y bloquea la sección del codigo que se encuentra antes del desbloqueo. Esto asegura que solo una goroutine pueda proceder a la vez.
- `lock.Unlock()`: Después de la sección crítica (actualizando `balance`), se libera el bloqueo, lo que permite que otras goroutines lo adquieran.
### Prevención de Condiciones de Carrera
Al poner el bloqueo mutex antes de acceder a `balance`, la función `Depositar` crea una sección crítica. Solo una goroutine puede tener el bloqueo a la vez, lo que garantiza que:
- Ninguna otra goroutine puede modificar `balance` mientras la actual lo está leyendo o actualizando.
- El valor leído de `balance` (almacenado en `b`) permanece constante durante la operación de depósito.
- La actualización final de `balance` refleja con precisión los depósitos combinados de todas las goroutines.
### En Resumen
El `sync.Mutex` en este código Go actúa como un bloqueo, asegurando que solo una goroutine pueda acceder y modificar la variable compartida `balance` a la vez. Esto evita las condiciones de carrera y garantiza actualizaciones consistentes del saldo, incluso en escenarios concurrentes.