Home > Backend Development > Golang > Why does the Go program print the sum of the computation before the message in the given code snippet, even though the main goroutine blocks until a signal is received from the channel?

Why does the Go program print the sum of the computation before the message in the given code snippet, even though the main goroutine blocks until a signal is received from the channel?

DDD
Release: 2024-10-29 21:49:29
Original
584 people have browsed it

Why does the Go program print the sum of the computation before the message in the given code snippet, even though the main goroutine blocks until a signal is received from the channel?

Go Concurrency and Channel Confusion

In Go, concurrency allows multiple tasks to execute concurrently using goroutines. Channels facilitate communication between these goroutines. However, understanding concurrency can be challenging, especially when dealing with channels.

Consider the following code snippet:

<code class="go">package main

import "fmt"

func display(msg string, c chan bool) {
    fmt.Println("display first message:", msg)
    c <- true
}

func sum(c chan bool) {
    sum := 0
    for i := 0; i < 10000000000; i++ {
        sum++
    }
    fmt.Println(sum)
    c <- true
}

func main() {
    c := make(chan bool)

    go display("hello", c)
    go sum(c)
    <-c
}</code>
Copy after login

In this code, we create two goroutines: display and sum. The display goroutine prints a message, sends a signal to the channel, and then waits for a response. The sum goroutine performs a long computation, prints the result, and also sends a signal to the channel. In the main goroutine, we block until a signal is received from the channel.

The expected output of the code is:

display first message: hello
Copy after login

However, we observe that the program prints both the message and the sum of the computation:

display first message: hello
10000000000
Copy after login

Understanding the Issue

The issue arises due to the nondeterministic nature of goroutine scheduling. The scheduler in Go chooses freely between the goroutines that are not blocked. In this example, the scheduler can execute any of the goroutines at any given time.

One possible execution order is:

  1. main creates the goroutines.
  2. The scheduler selects display, which prints the message and waits for a response.
  3. The scheduler switches to sum, which executes for a long time.
  4. The scheduler switches back to display, which sends the signal.
  5. The scheduler switches to main, which prints the signal and exits.

In this scenario, the sum is printed before display sends the signal, resulting in the unexpected output.

Solution

To ensure that the program prints only the message and exits before the sum is computed, we can use a different approach:

<code class="go">func main() {
    result := make(chan string)

    go display("hello", result)
    go sum(result)

    fmt.Println(<-result)
}</code>
Copy after login

In this revised version, the result channel carries a single value, the message from the display goroutine. The main goroutine now prints the value from the channel, ensuring that it receives the message before exiting.

The above is the detailed content of Why does the Go program print the sum of the computation before the message in the given code snippet, even though the main goroutine blocks until a signal is received from the channel?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
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