In PHP, it is common for the main coroutine to be blocked, leading to deadlock. During the execution of the main coroutine, if it encounters blocking operations, such as network requests, IO operations, or waiting for the results of other coroutines, if there is no appropriate handling method, deadlock may occur. In this case, the main coroutine cannot continue to execute, and other coroutines cannot get the opportunity to execute, and the entire program reaches a deadlock. So why is the main coroutine blocked in this case, causing a deadlock? Let’s answer this below.
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) } }
I mean, I know that for this code to work, the numbers should be sent to the numbers
channel in a separate goroutine, like:
go func() { for i := 0; i < 10; i++ { numbers <- i } }
Having said that, I find it hard to explain why the deadlock occurs. I'm well aware that the scheduler does not guarantee execution order. However, the first time you send to the numbers
channel in the loop, the main goroutine is blocked, but then the scheduler may start executing the square
goroutine, and then they communicate back and forth, which is not Is that so?
The reason why the main goroutine is blocked is that in this case, after sending the data to the squares channel, you are not reading any value from the squares channel.
When you do numbers <- i
, your go square
goroutine will receive the value and send it to the squares channel. However, at the same time, your main Goroutine will not receive values from the sqaures channel because your main Goroutine is still sending data to the Numbers channel.
This means your main coroutine will never execute this line for s := range squares
and then it will cause a deadlock.
In order to run this code correctly, you can modify it as shown below.
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) } }
The above is the detailed content of Why is the main coroutine blocked in this case, causing a deadlock?. For more information, please follow other related articles on the PHP Chinese website!