一、过程和线程

  1. 过程就是程序在操作系统中的一次执行过程,是零碎进行资源分配和调度的根本单位
  2. 线程是过程的一个执行实例,是程序执行的最小单元,它是比过程更小的能独立运行的根本单位
  3. 一个过程能够创立和销毁多个线程,同一个过程中的多个线程能够并发执行
  4. 一个程序至多有一个过程,一个过程至多有一个线程

二、并发和并行

  1. 多线程程序在单核上运行,就是并发
  2. 多线程程序在多核上运行,就是并行

并发 :在一个cpu中,比方10个线程,每个线程执行10毫秒(进行轮询操作),从人的角度看,如同10个线程都在运行,但从宏观上看,某一时间点看,其实只有一个线程在执行,这就是并发。
并行 :在多个cpu中(如10个),比方10个线程,每个线程执行10毫秒(各自在不同cpu上执行),从人的角度看,10个线程都在运行,但从宏观上看,某一时间点看,也同时10个线程在执行,这就是并行。

三、go协程和主线程

go主线程是一个物理线程,间接作用在CPU上,是重量级的,十分耗cpu资源,一个go线程上能够起多个协程。
协程是主线程开启的,轻量级的线程,逻辑态的,对资源耗费小
go协程特点:

  1. 有独立的栈空间
  2. 共享程序的堆空间
  3. 调度由用户管制
  4. 协程是轻量级的线程

四、channel(管道)

  1. channel实质是一个数据结构-队列
  2. 数据是先进先出
  3. 线程平安,多goroutine拜访时,不须要加锁,就是说channel自身是线程平安的
  4. channel是由类型的,一个string的channel只能寄存string类型的数据
  5. 遍历时,如果channel没有敞开,则会呈现deadlock谬误,

如果channel曾经敞开,则会失常遍历数据,遍历结束后,就会退出遍历

管道可申明为只读或只写
var cha1 chan int // 可读可写
var cha2 chan<- int // 只写
var cha2 <-chan int // 只读
应用select能够解决从管道取数据的阻塞问题
// 理论开发中,不好确定什么时候敞开该管道
// 可用select解决
for {
    select {
        // 如果管道始终没敞开,不会始终阻塞而deadlock
        // 会主动到下一个case匹配
        case v := <-intChan:
            fmt.Printf("读取数据")
        case v := <-stringChan:
            fmt.Printf("读取数据")
        default:
            fmt.Printf("都取不到")
    }
}
goroutine中应用recover,解决协程中呈现的panic,导致程序解体