Go Concurrency: Why Does My Program Print Unexpected Output When Using Channels?

DDD
Release: 2024-10-28 16:16:17
Original
914 people have browsed it

Go Concurrency: Why Does My Program Print Unexpected Output When Using Channels?

Go Concurrency and Channel Confusion Resolved

When working with concurrency in Go, channels play a pivotal role in communication between goroutines. However, their behavior can sometimes lead to confusion.

Consider the following Go program:

<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

The intended behavior is for the program to print "display first message: hello" and then exit. However, the actual output includes the result of the sum function:

display first message: hello
10000000000
Copy after login

Explanation

The confusion arises from the fact that the main goroutine blocks on the line:

<code class="go"><-c</code>
Copy after login

This means that the main goroutine cannot continue execution until it receives a value from channel c. Both display and sum send a true value to c, which unblocks the main goroutine. However, the scheduler can choose which goroutine to run first.

Possible Execution Order:

  1. Main creates two goroutines for display and sum.
  2. The scheduler runs display first, which prints the message and blocks on the channel send.
  3. The scheduler switches to the sum goroutine.
  4. Sum calculates and prints the result.
  5. The scheduler resumes display, which sends a value to the channel.
  6. The main goroutine receives the value and exits.

Solution

To ensure that the program prints only the first result, we can use a result channel:

<code class="go">func display(msg string, result chan string) {
    result <- msg
}</code>
Copy after login

And change the main function to:

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

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

The above is the detailed content of Go Concurrency: Why Does My Program Print Unexpected Output When Using Channels?. 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
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!