3 回答
TA贡献1820条经验 获得超9个赞
频道的源文件(来自你的 go 源代码根)在/src/pkg/runtime/chan.go 中。
hchan
是通道的中心数据结构,带有发送和接收链表(持有指向它们的 goroutine 和数据元素的指针)和一个closed
标志。有一个Lock
在 runtime2.go 中定义的嵌入式结构,根据操作系统用作互斥锁(futex)或信号量。锁定实现在 lock_futex.go (Linux/Dragonfly/Some BSD) 或 lock_sema.go (Windows/OSX/Plan9/Some BSD) 中,基于构建标签。
通道操作都在这个chan.go文件中实现,所以你可以看到makechan、send和receive操作,以及select构造、close、len和cap内置。
要深入了解通道的内部工作原理,您必须阅读Dmitry Vyukov 本人撰写的Go 通道(Go 核心开发人员、goroutines、调度程序和通道等)。
TA贡献1811条经验 获得超6个赞
查看通道的一种更简单的方法是,您可能希望在等待条件完成时暂停程序,通常用于防止 RACE 条件,这意味着一个线程可能不会在另一个线程之前完成,然后后来的线程或代码依赖有时不完成。一个例子可能是,您有一个线程从数据库或其他服务器检索一些数据并将数据放入变量、切片或映射中,但由于某种原因它被延迟了。那么您就有一个使用该变量的进程,但由于它尚未初始化,或者尚未获得其数据。程序失败。所以一个简单的看代码方式如下: package main
import "fmt"
var doneA = make(chan bool)
var doneB = make(chan bool)
var doneC = make(chan bool)
func init() { // this runs when you program starts.
go func() {
doneA <- true //Give donA true
}()
}
func initB() { //blocking
go func() {
a := <- doneA //will wait here until doneA is true
// Do somthing here
fmt.Print(a)
doneB <- true //State you finished
}()
}
func initC() {
go func() {
<-doneB // still blocking, but dont care about the value
// some code here
doneC <- true // Indicate finished this function
}()
}
func main() {
initB()
initC()
}
所以希望这会有所帮助。不是上面选择的答案,但我相信应该有助于消除谜团。我想知道我是否应该提出问题并自我回答?
- 3 回答
- 0 关注
- 242 浏览
添加回答
举报