我正在加速使用 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
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/