有缓冲的channel没有读完,close后还能继续读出里面的内容吗?


可以!

读取多次可以依次拿到之前写入的值,直到最后读完,继续读则得到对应channel类型的0值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package main

import (
"fmt"
)

func main() {
ch := make(chan int, 3)
fmt.Println(ch)
ch <- 123
ch <- 456
close(ch)

fmt.Println("从已关闭的channel中读取到信息为:", <-ch)
fmt.Println("从已关闭的channel中读取到信息为:", <-ch)
fmt.Println("从已关闭的channel中读取到信息为:", <-ch)
}
1
2
3
4
0x14000134000
从已关闭的channel中读取到信息为: 123
从已关闭的channel中读取到信息为: 456
从已关闭的channel中读取到信息为: 0


golang之channel入门

channel需要注意的点:

  • 关闭一个nil channel 会导致程序panic
  • channel关闭之后,仍然可以从channel中读取剩余的数据,直到数据全部读取完成。读取完后继续读,得到的将是对应类型的零值.

  • 而如果继续向已关闭的channel发送数据,会引起panic

  • channel不能关闭两次,否则会panic




A->B->C三个祖孙协程,B耗时最短,B执行结束后,C还会继续执行吗?


Go中父协程与子协程的生命周期问题

结论:

1. 当父协程是main协程时,父协程退出,父协程下的所有子协程也会跟着退出;
(当main协程结束时,子协程也是会被终止掉的)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main

import (
"fmt"
)

func main() {

fmt.Println(123)

go func() {
panic("子协程中发生异常")
}()

fmt.Println(456)

//time.Sleep(3e9)

}

输出:

1
2
123
456


2. 当父协程不是main协程时,父协程退出,父协程下的所有子协程并不会跟着退出(子协程直到自己的所有逻辑执行完或者是main协程结束才结束)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package main

import (
"fmt"
"time"
)

func main() {

fmt.Println(123)

go f1()

fmt.Println(456)

time.Sleep(5e9)

}

func f1() {

go func() {
time.Sleep(4e9)
fmt.Println("但f1()创建的协程还在像子弹一样继续飞!")
panic("子协程中发生异常")
}()

time.Sleep(2e9)
fmt.Println("f1()执行结束")
}
1
2
3
4
5
6
7
8
9
10
11
12
123
456
f1()执行结束
但f1()创建的协程还在像子弹一样继续飞!
panic: 子协程中发生异常

goroutine 33 [running]:
main.f1.func1()
/Users/fliter/go/src/shuang/0000/panic.go:25 +0x7c
created by main.f1
/Users/fliter/go/src/shuang/0000/panic.go:22 +0x24
exit status 2

go中父协程与子协程的生命周期(子协程能否使用主协程变量)




子协程panic,主协程还能不能正常运行? 主协程里的recover,能捕获子协程的panic吗?


不能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import (
"fmt"
"time"
)

func main() {

fmt.Println(123)

go func() {

panic("子协程中发生异常")
}()

fmt.Println(456)

time.Sleep(3e9)

}
1
2
3
4
5
6
7
8
9
10
123
456
panic: 子协程中发生异常

goroutine 4 [running]:
main.main.func1()
/Users/fliter/go/src/shuang/0000/panic.go:14 +0x2c
created by main.main
/Users/fliter/go/src/shuang/0000/panic.go:12 +0x64
exit status 2


主协程里的recover,能捕获子协程的panic吗?

不能~

对于goroutine中的panic,协程外面的recover是无法恢复的;goroutine中的recover,同样无法恢复协程外的panic

Go异常处理机制panic和recover




recover哪些情况下阻止不了程序崩溃?


不能~

  • 并发读写 map fatal error: concurrent map read and map write
  • 堆栈内存耗尽(如递归)
1
2
3
runtime: goroutine stack exceeds 1000000000-byte limit
runtime: sp=0xc0200e1bf0 stack=[0xc0200e0000, 0xc0400e0000]
fatal error: stack overflow
  • 将 nil 函数作为 goroutine 启动 fatal error: go of nil func value
  • goroutines 死锁 fatal error: all goroutines are asleep - deadlock!
  • 线程超过设置的最大限制 fatal error: thread exhaustion
  • 超出可用内存 fatal error: runtime: out of memory

总之 都会报fatal error:xxxxxxxx

recover能捕获所有错误吗?