Reputation:
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!
Upvotes: 9
Views: 590
Reputation: 94799
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:
main
creates two goroutinesdisplay
display
prints out the message and is blocked by the channel send (c <- true
) since there isn't a receiver yet.sum
nextsum
goroutine (it has already used a fair amount of time) and continues with display
display
sends the value to the channelBut 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)
.
Upvotes: 4