Home > Backend Development > Golang > Why is the main coroutine blocked in this case, causing a deadlock?

Why is the main coroutine blocked in this case, causing a deadlock?

PHPz
Release: 2024-02-09 15:42:09
forward
634 people have browsed it

Why is the main coroutine blocked in this case, causing a deadlock?

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.

Question content

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)
    }
}
Copy after login

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
}

}
Copy after login

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?

Workaround

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)
    }
}
Copy after login

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!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template