Go 如何实施围棋频道?

Go 如何实施围棋频道?,go,channel,Go,Channel,在(简要地)回顾了围棋语言规范、有效围棋和围棋记忆模型之后,我仍然有点不清楚围棋通道在引擎盖下是如何工作的 它们是什么样的结构?它们的行为有点像线程安全的队列/数组 它们的实现是否取决于体系结构?频道的源文件(来自您的go源代码根)位于 是通道的中心数据结构,具有发送和接收链接列表(保存指向其goroutine和数据元素的指针)和关闭标志。runtime2.go中定义了一个Lock嵌入式结构,根据操作系统的不同充当互斥(futex)或信号量。根据构建标记,锁定实现在lock_futex.go(L

在(简要地)回顾了围棋语言规范、有效围棋和围棋记忆模型之后,我仍然有点不清楚围棋通道在引擎盖下是如何工作的

它们是什么样的结构?它们的行为有点像线程安全的队列/数组


它们的实现是否取决于体系结构?

频道的源文件(来自您的go源代码根)位于

是通道的中心数据结构,具有发送和接收链接列表(保存指向其goroutine和数据元素的指针)和
关闭
标志。runtime2.go中定义了一个
Lock
嵌入式结构,根据操作系统的不同充当互斥(futex)或信号量。根据构建标记,锁定实现在lock_futex.go(Linux/Dragonfly/Some BSD)或lock_sema.go(Windows/OSX/Plan9/Some BSD)中

通道操作都在这个chan.go文件中实现,因此您可以看到makechan、发送和接收操作,以及select construct、close、len和cap内置


要深入了解通道的内部工作原理,您必须阅读Dmitry Vyukov本人(Go core dev、goroutines、scheduler和Channel等)的文章。

以下是一篇很好的演讲,大致描述了通道是如何实现的:

谈话内容:

2017年GopherCon大会:卡维亚·乔希-了解频道

通道为goroutine提供了一种简单的通信机制,并为构建复杂的并发模式提供了一种强大的构造。我们将深入研究通道和通道操作的内部工作方式,包括运行时调度器和内存管理系统如何支持它们


查看通道的一种更简单的方法就是这样,您可能希望在等待条件完成时暂停程序,通常用于防止争用条件,这意味着一个线程可能不会在另一个线程之前完成,然后您的后续线程或代码所依赖的某个线程或代码有时无法完成。 例如,您可以使用一个线程从数据库或其他服务器检索一些数据,并将数据放入变量、切片或映射中,由于某种原因,它会被延迟。然后你有一个使用这个变量的进程,但因为它还没有初始化,或者它还没有得到数据。程序失败了。 因此,在代码中查看它的简单方法如下: 包干管

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()
}
导入“fmt”
var doneA=制造(陈布尔)
var doneB=制造(chan bool)
var doneC=制造(chan bool)
func init(){//当程序启动时运行此命令。
go func(){
doneA看一看