前言:最近想接触一下分布式,因此我就学习了MIT的课程。做实验的时候需要用go,便也顺便了解一下go的语言特性。
channel
我一直没搞懂的是不带缓冲区的channel的阻塞问题,文档中说“如果通道未缓冲,则发送方将阻塞,直到接收方收到该值为止”,后来再仔细看了一下例子,豁然开朗。
让我们看一下这个例子
package main
import(
"fmt"
// "time"
)
func main(){
go func(){
fmt.Println("1")
}()
fmt.Println("2")
fmt.Println("3")
time.Sleep(1* time.Second)
}
因为主协程不会等待子协程执行结束,而是立即返回执行下一句代码,因此在这里我们加一个sleep以防子协程还未执行结束主协程已经退出了。
我们可以用channel来实现sleep的功能
package main
import(
"fmt"
// "time"
)
func main(){
c := make(chan int)
go func(){
fmt.Println("1")
<- c
}()
fmt.Println("2")
fmt.Println("3")
c <- 1
}
其中主协程通过信道发送数据,因为没有接受者,所以主协程会处于阻塞的状态,直到子协程完成数据接收,主协程才会退出
package main
import(
"fmt"
// "time"
)
func main(){
c := make(chan int)
go func(){
fmt.Println("1")
// <- c
}()
fmt.Println("2")
fmt.Println("3")
c <- 1
}
如果我们去掉子协程中接收数据的代码,就会发生死锁。