一、goroutine
格式
1 2 3 4 5 6
| go func(i int) { for { fmt.Printf("goroutine :%d \n",i) } }(i)
|
关键字 go + 函数,是一种协程 Coroutine
- 轻量级“线程”
- 非抢占式多任务处理,由协程主动交出控制权
- 编译器/解释器/虚拟机层面的多任务
- 多个协程可以在一个或多个线程上运行
- 不需要在定义时区分是不是异步
其他语言的协程
- C++ :Boost.Coroutine
- java 不支持
- python :yield 关键字实现协程
goroutine 切换点
I/O,select
channel
等待锁
函数调用(有时)
runtime.Gosched()
二、channel(通道)
1 2 3 4 5 6
| c := make(chan int) c <- 1 n := <-c
|
不要通过共享内存来通信,通过通信来共享内存
WaitGroup
通过共用系统 WaitGroup 等待 channel 任务做完
1 2 3 4
| var wg sync.WaitGroup wg.Add(20) wg.done() wg.Wait()
|
三、 select 进行调度
1 2 3 4 5 6 7 8
| select { case n := <-c1: values = append(values,n) case n := <-c2: values = append(values,n) case activeWorker <- activeValue: values = values[1:] }
|
四、传统的同步机制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| type atomicInt struct { value int lock sync.Mutex } func (a *atomicInt) increment() { fmt.Println("safe increment") func(){ a.lock.Lock() defer a.lock.Unlock() a.value++ }() } func (a *atomicInt) get() int { a.lock.Lock() defer a.lock.Unlock() return a.value }
|
五、CSP 模型
CSP(Communicating Sequential Process)模型是上个世纪七十年代提出的,用于描述两个独立的并发实体通过共享的通讯 channel(管道)进行通信的并发模型。 CSP中channel是第一类对象,它不关注发送消息的实体,而关注与发送消息时使用的channel。