L'éditeur PHP Xiaoxin est là pour vous présenter un problème courant de programmation simultanée : une impasse. Le blocage signifie que toutes les goroutines sont entrées en état de veille et ne peuvent pas continuer à s'exécuter même si des mécanismes tels que des groupes d'attente sont utilisés. Dans ce cas, toutes les goroutines sont incapables d’avancer, ce qui fait tomber le programme dans un état d’attente infinie. En programmation simultanée, il est très important d’éviter les blocages, et nous devons comprendre ses causes et ses solutions pour assurer le fonctionnement normal du programme.
J'apprends la simultanéité Go et je souhaite que deux routines Go continuent à communiquer entre elles tout en transmettant les valeurs mises à jour via un canal. L’un ajoute 2 et l’autre soustrait 1. Le code et le résultat sont les suivants :
Qu'est-ce qui ne va pas avec ce code ?
package main import ( "fmt" "sync" "time" ) var wg sync.waitgroup func addtwo(r chan int, e chan int) { val := <-r fmt.println("at recieved: ", val) time.sleep(1 * time.second) e <- val + 2 } func subtractone(r chan int, e chan int) { val := <-r fmt.println("so recieved: ", val) time.sleep(1 * time.second) e <- val - 1 } func main() { ch := make(chan int) ch2 := make(chan int) wg.add(1) go addtwo(ch, ch2) wg.add(1) go subtractone(ch2, ch) ch <- 1 wg.wait() }
Sortie :
AT Recieved: 1 SO Recieved: 3 fatal error: all goroutines are asleep - deadlock! goroutine 1 [semacquire]: sync.runtime_Semacquire(0x4b2de8?) /usr/lib/go-1.18/src/runtime/sema.go:56 +0x25 sync.(*WaitGroup).Wait(0x0?) /usr/lib/go-1.18/src/sync/waitgroup.go:136 +0x52 main.main()
Puis il s'arrête.
Pourquoi la goroutine n'échange-t-elle pas toujours les valeurs même si je n'appelle pas wg.done() dans la goroutine ?
Les deux goroutines que vous démarrez reçoivent simplement une valeur et envoient une valeur, puis se terminent. A partir de là, c'est juste main
goroutine,在 wg.wait()
处被阻止,因为你从未调用 wg.done()
.
Vous avez oublié d'utiliser la boucle (n infinie) :
func addtwo(r chan int, e chan int) { for { val := <-r fmt.println("at recieved: ", val) time.sleep(1 * time.second) e <- val + 2 } } func subtractone(r chan int, e chan int) { for { val := <-r fmt.println("so recieved: ", val) time.sleep(1 * time.second) e <- val - 1 } }
Avec ce changement, votre application s'exécutera pour toujours et le résultat sera :
AT Recieved: 1 SO Recieved: 3 AT Recieved: 2 SO Recieved: 4 AT Recieved: 3 SO Recieved: 5 AT Recieved: 4 ....
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!