美文网首页
Go控制程序生命周期

Go控制程序生命周期

作者: mick_ | 来源:发表于2019-11-05 10:30 被阅读0次

    近期学了go语言的并发编程,掌握了

    • 并发原语-原子锁,互斥锁,通道
    • 并发原理
    • 并发设计模式
      今天我们就来锻炼一下,如何用学到的新知识帮助我们更好的工作,学习下面的模式需要掌握
    • 通道使用
    • 类型函数
    • os.Signal信号
      今天的模式是控制程序的执行时间,大体思路是 执行一系列类型任务队列,在执行任务队列期间,系统中断,超时中断,完成中断,都会随时打断程序的执行并返回

    逻辑图如下

    执行任务.png

    代码如下

    package main
    
    import (
        "errors"
        "os"
        "os/signal"
        "time"
    )
    
    var (
        ErrTimeout   = errors.New("Timeout")
        ErrInterrupt = errors.New("Interrupt")
    )
    
    type RunnerFun func(int)
    
    // @title    获取一个任务队列
    // @description   获取一个任务队列
    // @param     d         time.Duration        "超时时间微妙"
    // @return              *Runner              "任务队列结构体"
    func NewRunner(d time.Duration) *Runner {
        return &Runner{
            timeout:   time.After(d),
            interrupt: make(chan os.Signal, 1),
            complete:  make(chan error),
        }
    }
    
    type Runner struct {
        tasks     []RunnerFun      `desc:"任务列表"`
        timeout   <-chan time.Time `desc:"超时通道"`
        interrupt chan os.Signal   `desc:"中断信号通道"`
        complete  chan error       `desc:"完成信号通道"`
    }
    
    // @title    添加执行任务
    // @description   添加执行任务到任务队列
    // @param     tasks     ...RunnerFun         "函数类型的参数"
    func (r *Runner) add(tasks ...RunnerFun) {
        r.tasks = append(r.tasks, tasks...)
    }
    func (r *Runner) start() error {
        // TODO  将中断通道传至Notify函数,获取系统的信号
        signal.Notify(r.interrupt, os.Interrupt)
        // TODO  执行任务,并获取结果
        go func() {
            r.complete <- r.run()
        }()
        // TODO  阻塞程序,直道超时或完成
        select {
        case <-r.timeout:
            return ErrTimeout
        case <-r.complete:
            return nil
        }
    }
    
    // @title    执行任务
    // @description   执行任务
    // @return                    error         "执行期间的错误"
    func (r *Runner) run() error {
        // TODO 遍历任务队列
        for i, task := range r.tasks {
            // TODO 无阻塞通道,当没有中断信号时,正常执行任务
            select {
            case <-r.interrupt:
                return ErrInterrupt
            default:
                task(i)
            }
        }
        return nil
    }
    

    相关文章

      网友评论

          本文标题:Go控制程序生命周期

          本文链接:https://www.haomeiwen.com/subject/ufksbctx.html