Home  >  Article  >  Backend Development  >  Why does my Go code print the sum of 10 billion numbers instead of just \"display first message: hello\"?

Why does my Go code print the sum of 10 billion numbers instead of just \"display first message: hello\"?

DDD
DDDOriginal
2024-10-28 07:49:02146browse

Why does my Go code print the sum of 10 billion numbers instead of just

Go Concurrency and Channel Confusion

Problem

A user is trying to understand Go concurrency and channels using 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>

The expected output is only "display first message: hello" because the main function should exit once it receives data from the channel. However, the actual output also includes the sum of 10 billion numbers.

Answer

The main issue in the code is that the scheduler can choose freely between the two goroutines (display and sum) that are not blocked. While the programmer expects display to finish first and send data to the channel before sum completes, this may not happen due to the non-deterministic nature of the scheduler.

In one possible execution scenario:

  1. main creates two goroutines for display and sum.
  2. The scheduler switches to display immediately.
  3. display prints its message and blocks waiting for a receiver to accept the data sent to the channel.
  4. The scheduler runs sum instead of resuming display.
  5. sum computes and prints the sum of 10 billion numbers.
  6. The scheduler chooses to resume display after sum finishes.
  7. display sends data to the channel.
  8. The scheduler switches to main to receive the data from the channel.
  9. main prints the sum and exits the program.

To address this issue and ensure that the "display first message: hello" message is printed exclusively, one approach is to use a result channel to receive the message from display and terminate the program immediately. The modified main function would be:

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

    go display("hello", result)
    fmt.Println(<-result)
}</code>

The above is the detailed content of Why does my Go code print the sum of 10 billion numbers instead of just \"display first message: hello\"?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
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