Maison  >  Article  >  développement back-end  >  Pourquoi le canal ne prend-il pas la dernière valeur déclarée ?

Pourquoi le canal ne prend-il pas la dernière valeur déclarée ?

WBOY
WBOYavant
2024-02-09 09:15:111104parcourir

Pourquoi le canal ne prend-il pas la dernière valeur déclarée ?

En PHP, le canal est un concept important utilisé en programmation concurrente. Il permet des opérations de communication et de synchronisation entre différentes goroutines. Cependant, une question courante est la suivante : « Pourquoi le canal ne prend-il pas la dernière valeur déclarée ? » Cette question implique les principes de conception et l’utilisation des canaux. Lorsque le canal reçoit des opérations, il bloque l'attente que l'expéditeur envoie des données. Lorsque l'expéditeur a fini d'envoyer les données, le destinataire peut poursuivre l'exécution. Par conséquent, la valeur d’un canal est déterminée lorsque l’expéditeur envoie des données, et non lorsque le destinataire reçoit des données. Il s’agit de garantir la fiabilité et la cohérence de la communication. Par conséquent, même si la dernière valeur déclarée a changé lorsque le récepteur la reçoit, le canal prendra toujours la valeur au moment de son envoi. Cela évite les incohérences et la confusion des données et garantit la fiabilité et l’exactitude des communications.

Contenu des questions

J'essaie de comprendre la chaîne. Dans ce code, je déclare les valeurs de 1 à 10. La valeur finale déclarée est 10, mais lorsque je l'imprime, elle renvoie toujours la valeur des deux déclarations avant before(8) . Je serais heureux si quelqu'un pouvait l'expliquer.

func main() {
    channel := make(chan int, 3)
    isOver := make(chan bool)

    go func() {
        for val := range channel {
            fmt.Println(val)
        }
        isOver <- true
    }()

    channel <- 1
    channel <- 2
    channel <- 3
    channel <- 4
    channel <- 5
    channel <- 6
    channel <- 7
    channel <- 8
    channel <- 9
    channel <- 10
    close(channel)

    fmt.Println("Channel Value is: ", <-channel)

    <-isOver

}

Lorsque je change la déclaration en 8, elle renvoie la valeur des deux déclarations précédentes, qui est 6.

Solution de contournement

Parce que vous avez défini 3 tailles de tampon pour le canal !

Remarque : votre exemple a des résultats différents selon les systèmes d'exploitation (par exemple, je reçois Channel 值为:0)

Réglez l'heure. Hibernez dans votre code et voyez ce qui se passe. Dans votre code :

<code>func main() {
    channel := make(chan int)
    isOver := make(chan bool)

    go func() {
        for val := range channel {
            fmt.Println(val)
            // sleep 1 second
            time.Sleep(1 * time.Second)
        }
        isOver <- true
    }()

    channel <- 1
    channel <- 2
    channel <- 3
    channel <- 4
    channel <- 5
    channel <- 6
    channel <- 7
    channel <- 8
    channel <- 9
    channel <- 10
    close(channel)

    fmt.Println("Channel Value is: ", <-channel)
    <-isOver
}

</code>

Le résultat est :

1
2
3
4
5
6
7
Channel Value is:  8
9
10

Remarque : Une meilleure façon de comprendre ce qui se passe dans votre code est de le suivre étape par étape.

Que s'est-il passé ? Voir cette trace :

1 // print 1 and sleep 1s
2,3,4 // stop for get values

3,4 // print 2 and sleep 1
3,4,5 // stop for get value

4,5 // print 3 and sleep 1
4,5,6 // stop for get value

5,6 // print 4 and sleep 1
5,6,7 // stop for get value

6,7 // print 5 and sleep 1
6,7,8 // stop for get value

7,8 // print 6 and sleep 1
7,8,9 // stop for get value

8,9 // print 7 and sleep 1
8,9,10 // stop for get value
// close channel
// in this line get value : fmt.Println("Channel Value is: ", <-channel)

9,10 // before get value
10 // get 9 and sleep 1
// get 10 and sleep 1

// isdone send signal true

Dans le code de suivi, lorsque la chaîne obtient les valeurs d'arborescence 8,9,10, la chaîne est fermée, à l'étape 2 quelque chose se passe :

1 - si goroutine obtient toutes les valeurs rapidement (la valeur du canal est : 0)
2 - Si la goroutine est occupée (la valeur du canal est : 7 ou 8 ou 9 ou 10)

Voir cette question pour plus de détails : Quand utiliser les canaux mis en mémoire tampon Et consultez ce site pour mieux comprendre : LIEN

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer