Condición de carrera en Golang

Según Wikipedia, la condición de carrera se define como la condición de una electrónica, software u otros sistemas donde el comportamiento sustantivo del sistema depende de la secuencia o el tiempo de otros eventos incontrolables. La condición de carrera cae bajo el departamento de «Concurrencia». La concurrencia es el arte de progresar en múltiples tareas simultáneamente. Entendamos qué significa realmente la concurrencia.

Considere el siguiente escenario para comprender mejor la concurrencia. Imagina una canasta llena de laddoos y dos personas de pie cerca de la canasta. A uno se le asigna una tarea para medir el conteo, la calidad, el peso y examinar otras características importantes de todos y cada uno de los laddu en la canasta. Ahora, tan pronto como comienza a observar los laddoos para sacar alguna conclusión, simultáneamente la segunda persona altera la forma de algunos laddoos, los golpea para que queden en polvo e incluso se come algunos pedazos de algunos laddoos. Está sucediendo simultáneamente: uno toma nota de las características de laddoos y el otro daña las características originales. Ahora no hay forma en el mundo de que el primero conozca los datos originales, ya que solo está tomando nota de los datos manipulados que incluso él desconoce. Esta es una condición de carrera.. Ambas tareas se ejecutan simultáneamente interfiriendo con algunas cosas comunes que conducen a una gran pérdida de datos.

¡Vamos a codificar y entender la condición de carrera de manera práctica!

package main
  
import (
    "fmt"
    "time"
)
  
func execute(some string) {
  
    // initializing a infinite for loop
    for i := 1; true; i++ {
  
        // prints string and number
        fmt.Println(some, i)
  
        // this makes the program sleep for
        // 100 milliseconds, wiz 10 seconds
        time.Sleep(time.Millisecond * 100)
  
    }
}
  
func main() {
  
    // Simple go synchronous program 
    // without any concurrency
    execute("First")
      
    // when this func is called it executes
    // and then passes on to next line
    execute("Second")
      
    // after the first second is to be executed
    // the problem is, execute function will 
    // never finish execution, its trapped 
    // in an infinite loop so the program will 
    // never move to second execution.
    fmt.Println("program ends successfully")
      
    // if I'm wrong and both first and second 
    // execute, then this line should print too
    // check the output
}

Race Condition in Golang

Si usa Windows, es probable que vea dicha salida en la pantalla. El resultado anterior continúa así y no tiene fin a menos que lo detenga manualmente o se quede sin memoria del sistema para su ejecución.

Considere el segundo código.

package main
  
import (
    "fmt"
    "time"
)
  
func execute(some string) {
  
    // initializing a infinite for loop
    for i := 1; true; i++ {
  
        // prints string and number
        fmt.Println(some, i)
  
        // this makes the program sleep for
        // 100 milliseconds, wiz 10 seconds
        time.Sleep(time.Millisecond * 100)
    }
}
  
func main() {
  
    // Simple go program with concurrency
    go execute("First")
  
    // Placing the go command infront of the
    // func call simply creates a goroutine
    execute("Second")
  
    // The goroutine ensures that both functions
    // execute simultaneously & successfully
    fmt.Println("program ends successfully")
  
    // This statement still won't execute because
    // the func call is stuck in an infinite loop
    // check the output
}

Race Condition in Golang with Examples

Si usa Windows, es probable que vea dicha salida en la pantalla. Cuando crea una gorutina en Go, generalmente hace que la ejecución sea más rápida al ceder el tiempo de espera a otras tareas prevalecientes. Ahora veamos qué sucede si crea dos gorutinas en el mismo programa.

package main
  
import (
    "fmt"
    "time"
)
  
func execute(some string) {
  
    // initializing a infinite for loop
    for i := 1; true; i++ {
  
        // prints string and number
        fmt.Println(some, i)
          
        // this makes the program sleep for
        // 100 milliseconds, wiz 10 seconds
        time.Sleep(time.Millisecond * 100) 
    }
}
  
func main() {
  
    // Simple go program with concurrency
    go execute("First")
      
    // Placing the go command in front of the
    // func call simply creates a goroutine
    go execute("Second")
      
    // The second goroutine, you may think that the
    // program will now run with lightning speed
    // But, both goroutines go to the background 
    // and result in no output at all Because the
    // program exits after the main goroutine
    fmt.Println("Program ends successfully")
      
    // This statement will now be executed
    // and nothing else will be executed
    // check the output
}

2 GoRoutines in Golang Causing Race Condition

Si usa Windows, es probable que vea dicha salida en la pantalla. Consideremos un escenario de condición de carrera para terminar nuestro tema:

package main
  
// one goroutine is the main
// goroutine that comes by default
import (
    "fmt"
    "runtime"
    "sync"
)
  
var wgIns sync.WaitGroup
  
func main() {
  
    // shared variable
    counter := 0
  
    // the other 10 goroutines are
    // supposed to come from here
    wgIns.Add(10)
    for i := 0; i < 10; i++ {
  
        // goroutines are made
        go func() {
            for j := 0; j < 10; j++ {
  
                // shared variable execution
                counter += 1
                // 100 should be the counter value but
                // it may be equal to 100 or lesser
                // due to race condition
            }
            wgIns.Done()
        }()
    }
  
    // this value should actually be 11
    fmt.Println("The number of goroutines before wait = ", runtime.NumGoroutine())
  
    wgIns.Wait()
  
    // value should be 100
    fmt.Println("Counter value = ", counter)
  
    fmt.Println("The number of goroutines after wait = ", runtime.NumGoroutine())
  
    // this value is supposed to be 1
    // but lets see if these values
    // stay consistently same every
    // time we run the code
}

Race Condition Practical Example in Golang

Esta inconsistencia ocurre debido a las condiciones de carrera. La condición de carrera en términos simples se puede explicar como, tienes un dulce y dos niños corren hacia ti diciendo que ambos tienen hambre. Ambos terminan peleando por ese chocolate, corren para conseguir los dulces. Esta es una condición de carrera. Aquí la solución es: conseguir otra golosina para que los dos disfruten tranquilamente de una golosina. Del mismo modo, podemos aumentar la asignación de recursos para garantizar que no se produzca la condición de carrera.

Publicación traducida automáticamente

Artículo escrito por ashika2k8 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *