【发布时间】:2021-10-11 21:48:56
【问题描述】:
我在 (https://www.geeksforgeeks.org/channel-in-golang/) 上读到:
"在通道中,默认情况下,发送和接收操作会阻塞,直到另一端没有准备好。 它允许 goroutine 在没有显式锁或条件变量的情况下相互同步。”
为了测试上面的语句,我写了一个下面提到的示例程序:
程序:
package main
import (
"fmt"
"sync"
"time"
)
func myFunc(ch chan int) {
fmt.Println("Inside goroutine:: myFunc()")
fmt.Println(10 + <-ch) //<-- According to rule, control will be blocked here until 'ch' sends some data so that it will be received in our myFunc() go routine.
}
func main() {
fmt.Println("Start Main method")
// Creating a channel
ch := make(chan int)
go myFunc(ch) //<-- This go routine started in a new thread
time.Sleep(2 * time.Second) //<--- introduced a Sleep of 2 seconds to ensure that myFunc() go routine executes before main thread
ch <- 10
fmt.Println("End Main method")
}
我期待以下输出:
Start Main method
Inside goroutine:: myFunc()
20
End Main method
但是,收到的实际输出是:
Start Main method
Inside goroutine:: myFunc()
End Main method
为什么不打印通过通道发送的值? 我想,这是因为主线程先完成了它的执行,因此所有其他 goroutine 也终止了。
如果是这样,那么,为什么规则说 - 它允许 goroutine 彼此同步无需显式锁或条件变量。
因为,为了得到预期的输出,我必须使用sync.WaitGroup 告诉主线程等待另一个 goroutine 完成。我使用的是waitgroup形式的锁,是不是违反了上面的规则?
PS:我正在学习 golang。因此,如果我完全错误地理解了这个概念,请原谅。
【问题讨论】:
-
我认为当接收方接收到值时,它会立即解除对发送方和接收方的阻塞。当 goroutine 运行时,main 函数继续打印并退出。如果 goroutine 能够及时打印,您将看到它或 main func 退出。尝试在本地多次运行您的代码,您将在两者之间看到
20。 -
In the channel, the send and receive operation block until another side is not ready by default中的措辞不是很好。他们一直阻塞,直到对方准备好读取/推送。