我的代码如下:
package main
import (
"fmt"
)
func main() {
c1 := make(chan int)
fmt.Println("push c1: ")
c1 <- 10
g1 := <- c1
fmt.Println("get g1: ", g1)
}
当我使用delve调试时,它会显示以下结果:
push c1:
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
D:/Go/projects/hello-world/src/ch9/code9_6/code1.go:10 +0xde
Process 6276 has exited with status 2
我不知道为什么,这只是一个简单的渠道示例,我制作了一个渠道,向它发送价值并从中获取价值,正因为如此,有人可以告诉我原因以及如何纠正它,Thx很多。
答案 0 :(得分:3)
引用https://tour.golang.org/concurrency/2:
默认情况下,发送和接收块,直到另一侧准备好为止。 这允许goroutine进行同步而无需显式锁定或 条件变量。
通道只能在goroutine之间工作,但是您只有1个通道。因此c1 <- 10
会阻止执行,直到某个人(通常在其他goroutine中)接收到该值。
要解决此问题:
package main
import (
"fmt"
)
func main() {
c1 := make(chan int)
go func() {
g1 := <- c1 // wait for value
fmt.Println("get g1: ", g1)
}()
fmt.Println("push c1: ")
c1 <- 10 // send value and wait until it is received.
}
尝试在The Go Playground中执行它。
我建议您从https://tour.golang.org/concurrency/1开始进行正式的Go并发之旅。
编辑:另一个选项是使用缓冲通道,如下所示。但是,使缓冲通道成为并非并不意味着它具有无阻塞的发送/接收操作。这只是意味着它将在队列中的N个值之后阻止发送,其中N始终是预定义的数字。在内部,它将发送的值存储到数组中,并在该数组被填充时阻塞直到接收到值(如非缓冲通道)为止。
package main
import (
"fmt"
)
func main() {
c1 := make(chan int, 1) // buffers 1 value without blocking.
fmt.Println("push c1: ")
c1 <- 10
g1 := <- c1
fmt.Println("get g1: ", g1)
}
在Go Playground上尝试。
答案 1 :(得分:0)
通道可以是缓冲的或非缓冲的(这意味着可以向其中发送变量的唯一值),并且当您尝试从非缓冲的通道读取数据时,您将锁定一个goroutine,在其中尝试执行此操作。为了解锁它,您必须在另一个goroutine中写入通道,反之亦然,也就是说,当您在通道中写入内容时,您将锁定执行该操作的goroutine,但是当您尝试从其中读取时,它将被解锁。另一个goroutine中的通道。您应该学习此功能,以开发灵活的(并发)程序。通道用于在必须独立或并行工作的不同例程之间发送数据。您可以创建一个包含两个,三个或更多goroutine的管道,以按顺序将数据从一个goroutine发送到另一个goroutine。
在此示例中,我创建了一个布尔类型为 ch 的通道。确切地说第9行和第11行将在第一行执行是不可能的。 sendq -是正在等待写入通道的列表goroutine。在这种情况下,主行( func main )例程正在等待执行第9行。
我们陷入僵局的另一个例子。执行将永远不会执行到第8行,因此我尝试将数据写入通道的goroutine(下一行)将永远不会启动。
有关渠道的更多信息,您可以在这里找到: http://dmitryvorobev.blogspot.com/2016/08/golang-channels-implementation.html
有m:n调度这样的术语。 Golang有一个m:n调度程序,Go调度程序可以在n个OS线程上调度m个例程。 https://medium.com/@riteeksrivastava/a-complete-journey-with-goroutines-8472630c7f5c
我建议您仔细阅读本书:https://www.amazon.com/Programming-Language-Addison-Wesley-Professional-Computing/dp/0134190440。我认为,这是有关Golang的最好的书,它描述了这种语言的许多概念和功能。
关于并发性和并行性之间的区别,您可以在这里阅读:https://www.ardanlabs.com/blog/2018/12/scheduling-in-go-part3.html