Goroutine(轻量级的线程,开线程没有数量限制)

1.进程和线程
  A.进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。
  B.线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。
  C.一个进程可以创建和撤销多个线程;同一个进程中的多个线程之间可以并发执行。

2、进程和线程

  ngix是多进程的单线程程序

 3.并发和并行
   A.多线程程序在一个核的cpu上运行,就是并发。go多线程的切换都是在用户态操作的,不像其他语言先切换到内核态,完成线程切换,然后返回用户态继续执行程序。
   B.多线程程序在多个核的cpu上运行,就是并行

4.协程和线程
  协程:独立的栈空间,共享堆空间,调度由用户自己控制,本质上有点类似于用户级线程,这些用户级线程的调度也是自己实现的
  线程:一个线程上可以跑多个协程,协程是轻量量级的线程。一个线程可以跑多个Goroutine。

5.goroutine调度模型

 M是物理线程,P是资源,G是Goroutine

 

如果有IO操作时,会新起一个线程等待IO操作的Goroutine

 

6.如何设置golang运行的cpu核数

  1.5之前go需要手动设置程序执行的内核数,1.5之后go自动设置

7、不同goroutine之间进行通讯  

  a.全局变量

  b.锁同步

  c.Channel(oroutine和channel相结合)

 8.goroutine中使用recover

应用场景,如果某个goroutine panic了,而且这个goroutine 里面没有捕获(recover),那么整个进程就会挂掉。所以,好的习惯是每当go产生一个goroutine,就需要写下recover。

 

Channel

1、channel概念 

  • 类似unix中管道(pipe) 
  • 先进先出
  • 线程安全,多个goroutine同时访问,不需要加锁
  • channel是有类型的, 一个整数的channel只能存放整数

2、 channel声明 

  var 变量量名 chan 类型 

  var test chan int 

  var test chan string 

  var test chan map[string]string 

  var test chan stu

3、channel初始化

  使用make进行初始化,比如: 

  var test chan int

  test = make(chan int, 10) 

  var test chan string

  test = make(chan string, 10)

4、channel基本操作

1. 从channel读取数据:

var testChan chan int

testChan = make(chan int, 10)

var a int

a = <- testChan

2. 从channel写 入数据:

var testChan chan int

testChan = make(chan int, 10)

var a int = 10

testChan <- a

5.带缓冲区的channel
   1.如下所示,testChan只能放 一个元素:
      var testChan chan int
      testChan = make(chan int)
      var a int
      a = <- testChan
   2.如下所示,testChan是带缓冲区的chan, 一次可以放10个元素:
      var testChan chan int
      testChan = make(chan int, 10)
      var a int = 10
      testChan <- a

 6. channel阻塞

7.chan之间的同步

8.for range遍历chan

9.chan的关闭  

  1.使用内置函数close进行关闭,chan关闭之后,for range遍历chan中已经存在的元素后结束  

  2.使用内置函数close进行关闭,chan关闭之后,没有使用for range的写法需要使用,v, ok := <- ch进行判断chan是否关闭 

10.chan的只读和只写  

  a.只读chan的声明   

    Var 变量量的名字 <-chan int   

    Var readChan <- chan int

    b.只写chan的声明   

    Var 变量量的名字 chan<- int   

    Var writeChan chan<- int

11. 对chan进行select操作
   Select {
       case u := <- ch1:
         case e := <- ch2:
         default: 
   }

定时器 

1、定时器的使用

2、一次定时器

3、超时控制

 

信号处理

单元测试

1.文件名必须以_test.go结尾
2.使用go test -v执行单元测试

calc.go

calc_test.go