Una pregunta de entrevista sobre goroutine

problema

package main

import (
 "fmt"
 "time"
)

func main() {
    
    
 ch1 := make(chan int)
 go fmt.Println(<-ch1)
 ch1 <- 5
 time.Sleep(1 * time.Second)
}

P:
¿Qué genera el código anterior?

¿Son las 5 o algo más?

análisis

Si el código se reemplaza de la siguiente manera:

package main

import (
 "fmt"
 "time"
)

func main() {
    
    
 ch1 := make(chan int)
  go func(){
    
    
    fmt.Println(<-ch1)
  }()
 ch1 <- 5
 time.Sleep(1 * time.Second)
}

Respuesta: El
problema anterior está causando un punto muerto.
El segundo caso es la salida normal 5.

Aquí se explica que los parámetros de la llamada de función después de la instrucción go se evaluarán primero, que es lo mismo que la evaluación de una llamada de función normal.
Esto significa que los parámetros reales se evalúan antes de llamar a la función.

Entonces, en esta pregunta, el <-ch1 en la instrucción go fmt.Println (<- ch1) se evalúa en la goroutine principal. Esto es equivalente a un canal sin búfer, tanto las operaciones de envío como las de recepción se realizan en una goroutine (goroutine principal), provocando un punto muerto.

Además, puede ver la diferencia entre los dos métodos anteriores a través de la compilación.

Expandir

Además, preste atención a la declaración de aplazamiento. Por ejemplo, el siguiente enfoque es incorrecto:

defer recover()

En su lugar, use este método:

 defer func() {
    
    
  if v := recover(); v != nil {
    
    
   _ = fmt.Errorf("PANIC=%v", v)
  }
 }()

Supongo que te gusta

Origin blog.csdn.net/csdniter/article/details/112968783
Recomendado
Clasificación