"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > ¿Cómo evitar un punto muerto al abarcar un canal almacenado en búfer en GoLang?

¿Cómo evitar un punto muerto al abarcar un canal almacenado en búfer en GoLang?

Publicado el 2024-11-02
Navegar:285

How to Avoid Deadlock When Ranging Over a Buffered Channel in GoLang?

Estancamiento en GoLang: ¿Por qué abarcar un canal con búfer?

Al utilizar canales con búfer en GoLang, es importante evitar crear una situación de punto muerto . Un problema reciente generó preocupaciones sobre un punto muerto encontrado al intentar abarcar un canal almacenado en búfer después de que se habían completado todas las gorutinas.

El código proporcionado intenta utilizar un canal almacenado en búfer con una capacidad de 4 y generar 4 gorutinas que envían datos al canal. Sin embargo, el punto muerto se produce porque:

  • El tamaño del canal es demasiado pequeño, lo que genera gorutinas bloqueadas esperando para escribir en el canal completo.
  • La operación de rango excesivo en el canal permanece indefinidamente esperando que lleguen los elementos, mientras no quedan gorutinas para escribir.

Solución 1: expandir el tamaño del canal y cerrar después de completarlo

Para resolver el punto muerto, el canal se puede aumentar de tamaño y cerrar después de que se hayan completado todas las gorutinas:

ch := make(chan []int, 5)
...
wg.Wait()
close(ch)

Sin embargo, esto elimina los beneficios de la canalización, ya que impide la impresión hasta que finalicen todas las tareas.

Solución 2: señal de finalización desde la rutina de impresión

Para habilitar la canalización real, se puede llamar a la función Done() dentro de la rutina de impresión:

func main() {
    ch := make(chan []int, 4)
    ...
    go func() {
        for c := range ch {
            fmt.Printf("c is %v\n", c)
            wg.Done()
        }
    }()
    ...
}

Este enfoque garantiza que la función Done() solo se llame después de que se haya impreso cada elemento, lo que indica de manera efectiva la finalización de cada rutina.

Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3