Maison  >  Article  >  développement back-end  >  Pourquoi la coroutine principale est-elle bloquée dans ce cas, provoquant un blocage ?

Pourquoi la coroutine principale est-elle bloquée dans ce cas, provoquant un blocage ?

PHPz
PHPzavant
2024-02-09 15:42:09604parcourir

Pourquoi la coroutine principale est-elle bloquée dans ce cas, provoquant un blocage ?

En PHP, il est courant que la coroutine principale soit bloquée, entraînant un blocage. Lors de l'exécution de la coroutine principale, si elle rencontre des opérations bloquantes, telles que des requêtes réseau, des opérations d'E/S ou l'attente des résultats d'autres coroutines, s'il n'y a pas de méthode de traitement appropriée, un blocage peut se produire. Dans ce cas, la coroutine principale ne peut pas continuer à s'exécuter, et les autres coroutines ne peuvent pas avoir la possibilité de s'exécuter, et l'ensemble du programme atteint une impasse. Alors pourquoi la coroutine principale est-elle bloquée dans ce cas, provoquant une impasse ? Répondons à cela ci-dessous.

Contenu des questions

package main

import "fmt"

func square(numbers chan int, squares chan int) {
    for n := range numbers {
        squares <- n * n
    }
    close(squares)
}

func main() {
    numbers := make(chan int)
    squares := make(chan int)

    go square(numbers, squares)

    for i := 0; i < 10; i++ {
        numbers <- i
    }
    close(numbers)

    for s := range squares {
        fmt.Println(s)
    }
}

Je veux dire, je sais que pour que ce code fonctionne, le numéro doit être envoyé au canal numbers dans une goroutine séparée, comme :

go func() {
for i := 0; i < 10; i++ {
    numbers <- i
}

}

Cela dit, j’ai du mal à expliquer pourquoi cette impasse se produit. Je suis bien conscient que le planificateur ne garantit pas l'ordre d'exécution. Cependant, n'est-il pas vrai que la première fois que vous envoyez au canal numbers 通道时,主 goroutine 被阻塞,但随后调度程序可能会开始执行 square dans la boucle, la goroutine principale est bloquée, mais le planificateur peut alors commencer à exécuter la goroutine square, puis ils communiquent en retour et en avant ?

Solution de contournement

La raison pour laquelle la goroutine principale est bloquée est que dans ce cas, après avoir envoyé les données au canal carrés, vous ne lisez aucune valeur du canal carrés.

Lorsque vous exécutez numbers 时,你的 <code>go square, la goroutine recevra la valeur et l'enverra au canal carrés. Cependant, en même temps, votre Goroutine principale ne recevra pas de valeurs du canal carrés car votre Goroutine principale envoie toujours des données au canal Numbers.

Cela signifie que votre coroutine principale n'exécutera jamais cette ligne for s := range squares et cela provoquera alors une impasse.

Afin d'exécuter correctement ce code, vous pouvez le modifier comme indiqué ci-dessous.

package main

import "fmt"

func square(numbers chan int, squares chan int) {
    for n := range numbers {
        squares <- n * n
    }
    close(squares)

}

func main() {
    numbers := make(chan int)
    squares := make(chan int)

    go square(numbers, squares)

    go func() {
        for i := 0; i < 10; i++ {
            numbers <- i
        }
        close(numbers)
    }()

    for s := range squares {
        fmt.Println(s)
    }
}

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