Go并发的控制

这里写了个定时任务调度的方案:由定时器去触发一个job,job的执行时间不定,需要有超时处理。
这里使用content中的withTimeout处理(与自己起个超时判断协程是一样的效果),主程等待协程的job执行,成功/超时都继续执行下次运行(当然也可以超时后关闭这个定时任务也是可以的)
这是个简单的定时小框架,其有可能可完善成一个完整的定时调度工具。

package main
import (
   "context"
   "fmt"
   "math/rand"
   "time"
)
func doJob(sig chan bool, timeout time.Duration) {
   ctx, cancel := context.WithTimeout(context.Background(), timeout) //超时控制
   defer cancel() //回调的方法入defer栈
   done := make(chan bool)
   go func(ctx context.Context) {
      fmt.Printf("->%s Dooing the Job\n", time.Now().Format("2006-01-02 15:04:05"))
      time.Sleep(time.Duration(rand.Intn(10)) * time.Second) //模拟一个随机执行时间的任务
      fmt.Printf("<-%s Ending the Job\n\n", time.Now().Format("2006-01-02 15:04:05"))
      done <- false
   }(ctx)
   select {
   case <-done: //任务完成了
      sig <- true
      return
   case <-ctx.Done(): //超时了
      sig <- false
      return
   }
}
func doRunTicker(duration time.Duration, timeout time.Duration) {
   sig := make(chan bool)
   timer := time.NewTimer(duration)
   for {
      <-timer.C //等待定时器信号
      go doJob(sig, timeout)
      if x := <-sig; !x {
         fmt.Printf("[E]%s 任务超时\n\n", time.Now().Format("2006-01-02 15:04:05"))
        //return //关闭任务
      }
      timer.Reset(duration) //重置定时器,开始下次任务
   }
}

func main() {
   rand.Seed(time.Now().UnixNano())
   doRunTicker(2*time.Second, 5*time.Second)
}

你可能感兴趣的:(Go并发的控制)