# 并發模式
* * * * *
--: 作者:Mick
時間:2018年11月26日
* * * * *
本章節是go并發變成的最后一章節
* [ ] 控制程序的生命周期
* [ ] 管理可復用的資源池
* [ ] 創建可以處理任務的 goroutine 池
基礎參考:https://blog.csdn.net/luckytanggu/article/details/79402802
### 案例一 Runner包
runner 包用于展示如何使用通道來監視程序的執行時間,如果程序運行時間用 runner 包來終止程序。當開發需要調度后臺處理任務的程序的時候,這種模式個程序可能會作為 cron 作業執行,或者在基于定時任務的云環境(如 iron.io)里讓我們來看一下 runner 包里的 runner.go
```
package runner
import (
"os"
"time"
"os/signal"
"errors"
)
//在給定超時時間內執行一組任務
//并在操作系統中發送中斷信號時結束這些任務
type Runner struct{
interrupt chan os.Signal
complete chan error
timeout <- chan time.Time
tasks []func(int)
}
func New(d time.Duration)*Runner{
return &Runner{
interrupt:make(chan os.Signal),
complete:make(chan error),
timeout:time.After(d),
}
}
func(r *Runner) Add(task ...func(int)) {
r.tasks = append(r.tasks,task...)
}
func(r *Runner) Start()error{
signal.Notify(r.interrupt,os.Interrupt)
go func(){
r.complete <- r.run()
}()
select{
case <- r.complete:
return nil
case <- r.timeout:
return errors.New("TimeOut")
}
}
func(r *Runner) run()error{
for id,task := range r.tasks{
select{
case <- r.interrupt:
signal.Stop(r.interrupt)
return errors.New("os.Notify signal.Stop")
default :
task(id)
}
}
return nil
}
```
### 案例二 Pool包
這個包用于展示如何使用有緩沖的通道實現資源池,來管理可以在
任意數量的goroutine之間共享及獨立使用的資源。這種模式在需要共享一組靜態資源的情況(如
共享數據庫連接或者內存緩沖區)下非 常有用。如果goroutine需要從池里得到這些資源中的一個,
它可以從池里申請使用完后歸還到資源
### 案例三 Work包
并控制一組工作,讓其并發執行。在這種情況下,使用無緩沖的通道要比隨意指定一個緩沖區大
小的有緩沖的通道好,因為這個情況下既不需要一個工作隊列,也不需要一組 goroutine 配合執7.3 work 169行。無緩沖的通道保證兩個 goroutine 之間的數據交換。這種使用無緩沖的通道的方法允許使用者知道什么時候 goroutine 池正在執行工作,而且如果池里的所有 goroutine 都忙,無法接受新的工作的時候,也能及時通過通道來通知調用者。使用無緩沖的通道不會有工作在隊列里丟失或者卡住所有工作都會被執行
```
package work
type Worker interface {
Work()
}
type Work struct{
work chan Worker
num int
}
func(w *Work) StartPools(num int){
for i:=0;i<num;i++{
go func(){
for v := range w.work{
v.Work()
}
}()
}
}
func(w *Work) Submit(ww Worker){
w.work <- ww
}
func(w *Work) Shutdown(){
close(w.work)
}
func New() *Work{
w := &Work{
work:make(chan Worker),
}
return w
}
```