質問

I'm new to Go and have a problem understanding the concurrency and channel.

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
}

The output of the program is:

display first message: hello
10000000000 

But I thought it should be only one line:

display first message: hello

So in the main function, <-c is blocking it and waits for the other two go rountines to send data to the channel. Once the main function receives the data from c, it should proceed and exit.

display and sum run simultaneously and sum takes longer so display should send true to c and the program should exit before sum finishes...

I'm not sure I understand it clearly. Could someone help me with this? Thank you!

役に立ちましたか?

解決

The exact output of your program is not defined and depends on the scheduler. The scheduler can choose freely between all goroutines that are currently not blocked. It tries to run those goroutines concurrently by switching the current goroutine in very short time intervals so that the user gets the feeling that everything happens simultanously. In addition to that, it can also execute more than one goroutine in parallel on different CPUs (if you happen to have a multicore system and increase runtime.GOMAXPROCS). One situation that might lead to your output is:

  1. main creates two goroutines
  2. the scheduler chooses to switch to one of the new goroutines immediately and chooses display
  3. display prints out the message and is blocked by the channel send (c <- true) since there isn't a receiver yet.
  4. the scheduler chooses to run sum next
  5. the sum is computed and printed on the screen
  6. the scheduler chooses to not resume the sum goroutine (it has already used a fair amount of time) and continues with display
  7. display sends the value to the channel
  8. the scheduler chooses to run main next
  9. main quits and all goroutines are destroyed

But that is just one possible execution order. There are many others and some of them will lead to a different output. If you want to print just the first result and quit the program afterwards, you should probably use a result chan string and change your main function to print fmt.Println(<-result).

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top