本文章为go语言体系课视频教程配套电子书,版权归 全栈编程@luboke.com所有,欢迎免费学习,转载必须注明出处!但禁止任何商业用途,否则将受到法律制裁!
死锁(deadlock)
当channel的某一端(sender/receiver)期待另一端的(receiver/sender)操作,另一端正好在期待本端的操作时,也就是说两端都因为对方而使得自己当前处于阻塞状态,这时将会出现死锁问题。
更通俗地说,只要所有goroutine都被阻塞,就会出现死锁。
比如,在main函数中,它有一个默认的goroutine,如果在此goroutine中创建一个unbuffered channel,并在main goroutine中向此channel中发送数据并直接receive数据,将会出现死锁:
package main
import (
"fmt"
)
func main (){
goo(32)
}
func goo(s int) {
counter := make(chan int)
counter <- s
fmt.Println(<-counter)
}
在上面的示例中,向unbuffered channel中send数据的操作counter <- s
是在main goroutine中进行的,从此channel中recv的操作<-counter
也是在main goroutine中进行的。send的时候会直接阻塞main goroutine,使得recv操作无法被执行,go将探测到此问题,并报错.
要修复此问题,只需将send操作放在另一个goroutine中执行即可:
package main
import (
"fmt"
)
func main() {
goo(32)
}
func goo(s int) {
counter := make(chan int)
go func() {
counter <- s
}()
fmt.Println(<-counter)
}
或者,将counter设置为一个容量为1的buffered channel
这样放完一个数据后send不会阻塞(被recv之前放第二个数据才会阻塞),可以执行到recv操作
package main
import (
"fmt"
)
func main (){
goo(32)
}
func goo(s int) {
//将counter设置为一个容量为1的buffered channel,这样放完一个数据后send不会阻塞(被recv之前放第二个数据才会阻塞),可以执行到recv操作。
counter := make(chan int,1)
counter <- s
fmt.Println(<-counter)
}
buffered channel 实现fibonacci、for ...range channel
package main
import "fmt"
func main() {
//Range 和 Close
//上面这个例子中,我们需要读取两次 c,这样不是很方便,Go 考虑到了这一点,所以也可以通过 range,像操作 slice 或者 map 一样操作缓存类型的 channel
channel3 := make(chan int, 10)
go fibonacci(cap(channel3), channel3)
for i := range channel3 {
fmt.Println(i)
}
fibonacci2(10)
//for i := range c 能够不断的读取 channel 里面的数据,直到该 channel 被显式的关闭。上面代码我们看到可以显式的关闭 channel,生产者通过内置函数 close 关闭 channel。关闭 channel 之后就无法再发送任何数据了,在消费方可以通过语法 v, ok := <-ch 测试 channel 是否被关闭。如果 ok 返回 false,那么说明 channel 已经没有任何数据并且已经被关闭。
//记住应该在生产者的地方关闭 channel,而不是消费的地方去关闭它,这样容易引起 panic
//另外记住一点的就是 channel 不像文件之类的,不需要经常去关闭,只有当你确实没有任何发送数据了,或者你想显式的结束 range 循环之类的
}
func fibonacci(n int, c chan int) {
x, y := 1, 1
for i := 0; i < n; i++ {
c <- x
x, y = y, x + y
}
close(c)
}
func fibonacci2(n int) {
x, y := 1, 1
for i := 0; i < n; i++ {
fmt.Println(x)
x, y = y, x + y
}
}
本文章为go语言体系课视频教程配套电子书,版权归 全栈编程@luboke.com所有,欢迎免费学习,转载必须注明出处!但禁止任何商业用途,否则将受到法律制裁!