对于具有一个 goroutine 的无缓冲通道:否(原因:按设计):
您可以使用缓冲通道和一个 goroutine 或
两个使用非缓冲通道的 goroutine 以避免死锁:
如果通道没有缓冲,发送方会阻塞,直到接收方有
收到了价值。如果通道有缓冲区,则发送方阻塞
仅在将值复制到缓冲区之前;如果缓冲区是
已满,这意味着等到某个接收器检索到一个值。
1- 使用 缓冲通道:main 本身就是一个 goroutine,如果您需要在一个 goroutine 中执行此操作,您应该像这样使用缓冲通道:
package main
import (
"fmt"
"time"
)
func main() {
ch1 := make(chan int, 1)
for {
select {
case ch1 <- 1:
fmt.Println("sent 1 ")
case c := <-ch1:
fmt.Println(" received ", c)
}
time.Sleep(time.Second)
}
}
输出:
sent 1
received 1
sent 1
received 1
sent 1
received 1
2- 使用无缓冲通道:您可以在一个select 中的两个case 语句中发送和接收到无缓冲通道,您需要两个goroutines,见:
试试this:
package main
import (
"fmt"
"time"
)
func main() {
go ct("Alex")
go ct("John")
//select {}
time.Sleep(300 * time.Millisecond)
}
func ct(name string) {
for {
select {
case ch1 <- 1:
fmt.Println(name, "sent 1")
case c := <-ch1:
fmt.Println(name, "received:", c)
}
fmt.Println(name, "waiting...")
time.Sleep(100 * time.Millisecond)
}
}
var ch1 = make(chan int)
输出:
John sent 1
John waiting...
Alex received: 1
Alex waiting...
John received: 1
John waiting...
Alex sent 1
Alex waiting...
John sent 1
John waiting...
Alex received: 1
Alex waiting...