go - 为什么 golang 中的 channel 需要一个 go-routine?

标签 go

我正在加速使用 golang 中的 channel 。根据其documentation ,

Channels are a typed conduit through which you can send and receive values with the channel operator, <-.

我明白了。我从使用 go routines 的示例中了解它是如何使用的。我尝试了一个非常简单的例子。它会导致程序死锁。忽略这个程序的无意义,你能告诉我为什么这是僵局吗?

package main
import  "fmt"
func main() {
    c := make(chan int)
    c <- 17
    fmt.Println(<- c)
}

引用文档补充说

By default, sends and receives block until the other side is ready.

好的,在上面的例子中,当 c <- 17 时,发送方(主程序)准备好发送了遇到了。所以不应该执行。随后 Println应该能够排出 channel 。

我意识到如果 c <- 17 一切正常被替换为

go func() { c <- 17 } ()

只是想了解为什么这是必要的。

最佳答案

The Go Programming Language Specification

Channel types

A channel provides a mechanism for concurrently executing functions to communicate by sending and receiving values of a specified element type.

A new, initialized channel value can be made using the built-in function make, which takes the channel type and an optional capacity as arguments:

make(chan int, 100)

The capacity, in number of elements, sets the size of the buffer in the channel. If the capacity is zero or absent, the channel is unbuffered and communication succeeds only when both a sender and receiver are ready. Otherwise, the channel is buffered and communication succeeds without blocking if the buffer is not full (sends) or not empty (receives). A nil channel is never ready for communication.


你问:为什么 golang 中的一个 channel 需要一个 go-routine?

Go channel 不需要 goroutine。成功的发送只需要一个就绪的接收者或一个未满的缓冲区。例如,使用缓冲 channel ,

package main

import "fmt"

func main() {
    c := make(chan int, 1)
    c <- 17
    fmt.Println(<-c)
}

输出:

17

您的示例失败,因为它试图在没有准备好的接收器的无缓冲 channel 上发送。

package main

import "fmt"

func main() {
    c := make(chan int)
    c <- 17
    fmt.Println(<-c)
}

输出:

fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
    /home/peter/gopath/src/sri.go:7 +0x59

@Tim Cooper's proposed solution有同样的错误。

package main

import "fmt"

func main() {
    c := make(chan int)
    select {
    case c <- 17:
    default:
    }
    fmt.Println(<-c)
}

输出:

fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.main()
    /home/peter/gopath/src/tim.go:11 +0x8a

关于go - 为什么 golang 中的 channel 需要一个 go-routine?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44216442/

相关文章:

debugging - 在vs-code中调试go-lang时如何指定生成的调试二进制文件的路径

go - 如何在 golang net/smtp.sendmail 中定义发件人姓名?

MySQL 插入 Float32 和 Float64 Go

go - Go 函数中返回变量的个数可变

interface - 转到 : panic errors from BST and interface conversion

javascript - 如何在 Google map 服务的 Go 客户端中使用方向响应?

javascript - 如何从等式到使用 javascript 进行编码

go - 如何将我的链码从本地转换为 super 账本结构中的对等体?

go - 是否可以保证成员调用之间的评估顺序?

go - VPP插件可以用Go实现吗?