Golang

panic 和 defer

panic

panic可以直接从代码初始化:当错误条件很严苛且不可恢复,程序不能继续运行时,可以使用panic函数产生一个中止程序的运行时错误。panic接收一个做任意类型的参数,通常是字符串,在程序死亡时被打印出来。不能随意地用panic中止程序,必须尽力补救错误让程序能继续执行。

recover

recover内建函数被用于从panic或错误场景中恢复:让程序可以从panicking重新获得控制权,停止终止过程进而恢复正常执行。

recover只能在defer修饰的函数中使用,用于取得panic调用中传递过来的错误值,如果是正常执行,调用recover会返回nil,且没有其它效果。

panic会导致栈被展开直到defer修饰的recover被调用或者程序中止

如果在一个 goroutine 里面发生的 panic,这个错误能捕捉吗

  • panic 会停止整个进程,不仅仅是当前goroutine,也就是说整个程序都会凉凉
  • panic是有序的、可控的停止程序,不是啪唧一下就宕掉了,所以我们还可以用recover补救
  • recover只能在defer里面生效,如果不是在defer里调用,会直接返回nil
  • 很重要的一点是:goroutine发生panic时,只会调用自身的defer,所以即便主goroutine里写了recover逻辑,也无法拯救到其它goroutine里的panic

进程、线程、协程

进程

进程是系统资源分配的最小单位,进程占用的资源有:地址空间,全局变量,文件描述符,各种硬件等等资源。

线程

进程是线程的容器,线程共享进程的大部分资源,并参与CPU的调度。线程自己也是拥有自己的资源的,例如,栈,寄存器等等。 线程也是有着自己的缺陷的,例如健壮性差,若一个线程挂掉了,整一个进程也挂掉了,这意味着其它线程也挂掉了,进程却没有这个问题,一个进程挂掉,另外的进程还是活着。

协程

协程通过在线程中实现调度,避免了陷入内核级别的上下文切换造成的性能损失,进而突破了线程在IO上的性能瓶颈