Why is "Greetings done" getting printed before "Bonjour" in the below example of goroutines and channels?

huangapple go评论83阅读模式
英文:

Why is "Greetings done" getting printed before "Bonjour" in the below example of goroutines and channels?

问题

在下面的示例中,为什么在“Bonjour”之前打印出“Greetings done”?发送程序不应该等待接收程序接收通道中的值吗?

package main

import (
	"fmt"
)

func greetings(c chan string) {
	fmt.Println(<-c)
	c <- "Bonjour"
	fmt.Println("Greetings done")
}

func main() {
	myChannel := make(chan string)

	// 创建协程并由Go执行
	go greetings(myChannel)

	// 当greetings()协程正在执行时,主函数通过通道写入一个新值
	myChannel <- "hi from main"
	// 现在主函数(发送程序)被阻塞。它不会继续执行,直到另一个协程从通道中读取值

	// 在此之前,greetings()协程将读取该值并打印。因此,“hi from main”被打印出来

	// 现在主函数继续执行并移到下一行
	// 与此同时,greetings()协程将“Bonjour”写入通道

	// 主函数将接收它并打印
	fmt.Println(<-myChannel)
	fmt.Println("main done")
}

程序的输出是:
hi from main
Greetings done
Bonjour
main done

发送程序不应该等待接收程序接收通道中的值吗?也就是说,发送程序(greetings)将被阻塞,直到主程序接收到它的值。

英文:

In the below example, Why is "Greetings done" getting printed before "Bonjour" ? Shouldn't the sender routine wait until receiver routine receives the value in channel ?

package main

import (
	&quot;fmt&quot;
)

func greetings(c chan string) {
	fmt.Println(&lt;-c)
	c &lt;- &quot;Bonjour&quot;
	fmt.Println(&quot;Greetings done&quot;)
}

func main() {
	myChannel := make(chan string)

	// creates routine and leaves it upto Go to execute
	go greetings(myChannel)

	// while greetings() routine is getting executed, a new value is written to channel by main function
	myChannel &lt;- &quot;hi from main&quot;
	// now main function (sender routine) is blocked. It wont proceed until another routine reads from the channel

	// By then greetings() routine will read the value and prints it. Hence &quot;hi from main&quot; gets printed

	// Now main function proceeds and moves to next line
	// simultaneously, greetings() would have written &quot;Bonjour&quot; to channel

	// main routine will receive it and prints it
	fmt.Println(&lt;-myChannel)
	fmt.Println(&quot;main done&quot;)
}

The output of the program is:
hi from main
Greetings done
Bonjour
main done

Shouldn't the sender routine wait until receiver routine receives the value in channel ?
Meaning Shouldn't "Greetings done" be printed after "Bonjour" ? Because the sender routine (greetings) will be blocked until the main routine receives its value.

答案1

得分: 2

“Greetings done”和“Bonjour”之间没有定义的顺序关系。换句话说,它们可以以任何顺序出现,这仍然是程序的有效行为。

“Greetings done”不应该在“Bonjour”之后打印吗?因为发送例程(greetings)将被阻塞,直到主例程接收到它的值。

发送例程被阻塞直到主例程接收到它的值是正确的。然而,主例程必须在接收到值之后才能打印该值。

    // 主例程接收并打印该值
    fmt.Println(<-myChannel)

这个注释基本上是正确的,但仅仅因为它执行了A和B(接收和打印),并不意味着A和B同时发生。只有接收值的操作是同步的。

英文:

"Greetings done" and "Bonjour" have no defined order with respect to each other. In other words, they may appear in either order, and that would still be valid behaviour of the program.

> Shouldn't "Greetings done" be printed after "Bonjour" ? Because the sender routine (greetings) will be blocked until the main routine receives its value.

It's correct that the sender will be blocked until the main goroutine receives its value. Still, the main goroutine must print the value after receiving it.

    // main routine will receive it and prints it
    fmt.Println(&lt;-myChannel)

This comment is basically correct, but just because it does A and B (receives and prints), doesn't mean A and B happen at the same time. It's only the receiving of the value that is synchronized.

huangapple
  • 本文由 发表于 2022年6月18日 02:45:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/72663589.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定