我可以使用make(chan someStruct)吗?

GZ *_*Xue 6 struct deadlock channel go goroutine

例如:

type name struct {
    name string
    age int
}

func main() {
      c := make(chan name)

      c <- name{"sfsaf", 1}
      a, b := <- c

      close(c)
}
Run Code Online (Sandbox Code Playgroud)

结果:

致命错误:所有goroutines都睡着了 - 僵局!

我想通过渠道传递价值.我该怎么办?

edu*_*911 7

是的,你可以通过结构.但这不是你的OP中的问题.

当没有接收器准备接收时,您在通道上发送了一个值.这就是造成你僵局的原因.

频道希望receiver阻止,等待sender.这是通过Goroutines完成的.

因此,请将您的发件人包装在goroutine中,该goroutine不会立即执行.

package main

import (
    "fmt"
)

type name struct {
    name string
    age  int
}

func main() {
    c := make(chan name)

    go func() {
        c <- name{"sfsaf", 1}
        close(c)
    }()

    for n := range c {
        fmt.Println(n)
    }

    fmt.Println("channel was closed (all done!).")
}
Run Code Online (Sandbox Code Playgroud)

在操场上看到它:https://play.golang.org/p/uaSuCaB4Ms

这是因为发件人的goroutine尚未执行.直到当前的goroutine执行被阻止.

我们在for n := range c循环中受阻.这是接收器,坐着等待价值观.(这是一种常见的模式,使用for循环迭代通道值,因为它将坐下并阻塞,等待值).

所以现在我们被阻止等待接收for循环中的值,内联gorouting现在将执行,以在通道上发送我们的值.

此外,我们遵循安全实践并在我们自己和close(c)渠道之后整理,发出for循环或select声明,表示不再发送任何值. 发件人总是关闭,而不是收件人.这是for范围循环用于退出for循环的模式,并继续执行其余代码.


作为旁注,你通过传递结构的值 - 而不是指针 - 做得很好.

如果你传递了一个指针,你必须在对象周围实现一些互斥锁,以防止R/W恐慌.

不要通过共享内存进行通信; 相反,通过沟通分享记忆.

坚持传递价值,而不是指针,围绕你的渠道和goroutines,并获得好处.

  • 我明白了,应该使用 (&lt;-c).age 来获取结构的某个元素 (2认同)