# 并发模式
* * * * *
--: 作者: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
}
```