0%

Go语言协程

一个现代编译器的主要工作流程如下:源代码(source code)->预处理器(preprocessor)->编译器(compiler)->汇编程序(assembler)->目标代码(object code)->链接器(linker)->可执行文件(executables),最后打包好的文件给电脑运行。

一、基础

      Go语言协程本质上是用户级线程,在运行时通过调度器将用户级线程交给操作系统的系统级线程去处理。如果在运行过程中遇到某个IO操作而暂停运行,调度器会将用户级线程和系统级线程分离以便让系统级线程去处理其他用户级线程;而当IO操作完成需要恢复运行时,调度器又会调度空闲的系统级线程来处理这个用户级线程,从而达到并发处理多个协程的目的。

  1. 协程通信

    • 共享内存
      • 全局变量为所有协程共享
      • 互斥锁防止全局变量污染
    • 通道
    • Context包
    • sync.WaitGroup
  2. 协程泄露

二、使用

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
31
32
33
34
35
36
37
38
39
package main

import (
"fmt"
"runtime"
"sync"
"time"
)

var counter int = 0

func add(a, b int, lock *sync.Mutex) {
c := a + b
lock.Lock()
counter++
fmt.Printf("%d: %d + %d = %d\n", counter, a, b, c)
lock.Unlock()
}

func main() {
start := time.Now()
lock := &sync.Mutex{}
for i := 0; i < 10; i++ {
go add(1, i, lock)
}

for {
lock.Lock()
c := counter
lock.Unlock()
runtime.Gosched()
if c >= 10 {
break
}
}
end := time.Now()
consume := end.Sub(start).Seconds()
fmt.Println("runtime(s):", consume)
}

三、参考

  1. 参考一
  2. 参考二
  3. 参考三
  4. 参考四
  5. 参考五