blocage de canal

-Fils légers
-Partager la mémoire via la communication, et la transmission des messages est réalisée via des canaux.

Du point de vue de l'émetteur :
  ch <- x // a send statement
- Pour le même canal, l'opération d'envoi est bloquée jusqu'à ce que le récepteur soit prêt.
-Les données du canal ne sont pas reçues, puis d'autres données sont transmises au canal.
Angle du récepteur :

		x = <-ch // a receive expression in an assignment statement
		<-ch     // a receive statement; result is discarded
	接收操作是阻塞的(协程或函数中的),直到发送者可用
	如果通道中没有数据,接收者就阻塞了。

```go
 package main
 2 
 3 import (
 4     "fmt"
 5 )
 6 
 7 func f1(in chan int) {
    
    
 8     fmt.Println(<-in)
 9 }
10 
11 func main() {
    
    
12     out := make(chan int)
13     out <- 2
14     go f1(out)
15 }
func main() {
    
    
    conn, err := net.Dial("tcp", "localhost:8000")
    if err != nil {
    
    
        log.Fatal(err)
    }
    done := make(chan struct{
    
    })
    go func() {
    
    
        io.Copy(os.Stdout, conn) // NOTE: ignoring errors
        log.Println("done")
        done <- struct{
    
    }{
    
    } // signal the main goroutine
    }()
    mustCopy(conn, os.Stdin)
    conn.Close()
    <-done // wait for background goroutine to finish
}

Ainsi, la fonction principale ne doit pas avoir de conn <- l'opération d'envoi doit être dans un groutine ou après l'acceptation

Résultat courant : erreur fatale : toutes les goroutines sont endormies - impasse !

C'est parce qu'il n'y a pas de réception de out avant la ligne 13, donc pour out <- 2, il sera toujours bloqué, c'est-à-dire qu'il attendra indéfiniment.

Il y a une opération de lecture sur le pipeline avant que la ligne 13 et la ligne 14 ne soient échangées
    , donc out <- 2 est légal. Comme mentionné ci-dessus, l'opération d'envoi est bloquée jusqu'à ce que le récepteur soit prêt.

L'arrêt
et l'envoi d'opérations provoqueront une exception de panique.
L'opération de réception peut toujours accepter des données qui ont été envoyées avec succès auparavant ;
s'il n'y a pas de données dans le canal, des données de valeur nulle seront générées.

Lire avancé :

 go func() {
    
    
        for x := range naturals {
    
    
            squares <- x * x
        }
        close(squares)
    }()

** Fermez chaque canal.
Le seul moment pour fermer le canal est de dire à la routine du récepteur que toutes les données ont été envoyées.

おすすめ

転載: blog.csdn.net/qq_34751210/article/details/127771103