golang学习笔记之手写一个执行器
来源:互联网 发布:软件客户端界面设计 编辑:程序博客网 时间:2024/06/05 17:00
之前介绍过一个多协程的Parallelize,允许多个协程并发执行任务的函数,今天手写一个控制能力更强的的ruuner,初步实现单个协程处理,后续将继续改进为多协程处理:
package runnerimport ( "errors" "os" "os/signal" "time" )type Runner struct { // interrupt channel reports a signal from the // operating system. interrupt chan os.Signal // complete channel reports that processing is done. complete chan error // timeout reports that time has run out. timeout <-chan time.Time // tasks holds a set of functions that are executed // synchronously in index order. tasks []func(int)}// ErrTimeout is returned when a value is received on the timeout.var ErrTimeout = errors.New("received timeout")// ErrInterrupt is returned when an event from the OS is received.var ErrInterrupt = errors.New("received interrupt")// New returns a new ready-to-use Runner.func New(d time.Duration) *Runner { return &Runner{ interrupt: make(chan os.Signal, 1), complete: make(chan error), timeout: time.After(d), }}// Add attaches tasks to the Runner. A task is a function that// takes an int ID.func (r *Runner) Add(tasks ...func(int)) { r.tasks = append(r.tasks, tasks...)}// Start runs all tasks and monitors channel events.func (r *Runner) Start() error { // We want to receive all interrupt based signals. // Run the different tasks on a different goroutine. go func() { r.complete <- r.run() }() select { // Signaled when processing is done. case err := <-r.complete: return err // Signaled when we run out of time. case <-r.timeout: return ErrTimeout } }// run executes each registered task.func (r *Runner) run() error { for id, task := range r.tasks { // Check for an interrupt signal from the OS. if r.gotInterrupt() { return ErrInterrupt } // Execute the registered task. task(id) } return nil }// gotInterrupt verifies if the interrupt signal has been issued.func (r *Runner) gotInterrupt() bool { select { // Signaled when an interrupt event is sent. case <-r.interrupt: // Stop receiving any further signals. signal.Stop(r.interrupt) return true // Continue running as normal. default: return false }}
注解写的很详细,我简单介绍一下;Runner是一单协程的运行器,里面几个属性interrupt获取os的信号量,complete返回执行结果,timeout设置超时时间,如果超时结束运行,tasks是报错任务的。添加任务通过Add方法:将方法加入到切片中,Start方法启动任务,这里只启动一个协程,后期改进,run方式是具体执行,执行task函数gotInterrupt获取os的消息。
怎样使用呢?看下面:
const timeout = 2*time.Secondfunc main() { r := runner.New(timeout) r.Add(crateTask(),crateTask(),crateTask()) if err := r.Start(); err != nil { switch err { case runner.ErrTimeout: fmt.Println("timeout error") os.Exit(1) case runner.ErrInterrupt: fmt.Println("interrupt error") os.Exit(2) } } log.Println("end !!!!")}func crateTask()func(int) { return func(id int) { fmt.Println("exec id :",id) time.Sleep(time.Duration(id)*time.Second) }}
通过改变timeout时间可以准确的控制任务执行时间,上面2秒的例子,保证每个任务都能运行,执行结果如下:
exec id : 0
exec id : 1
exec id : 2
timeout error
exit status 1
如果改成5s当然能保证执行完成任务:
exec id : 0
exec id : 1
exec id : 2
2017/04/11 09:59:12 end !!!!
0 0
- golang学习笔记之手写一个执行器
- golang学习笔记之---waitgoup
- golang学习笔记之range
- golang学习笔记之赋值
- Golang 学习笔记 ---类型和一个 HelloWorld
- Golang之bytes.buffer学习笔记
- golang学习笔记之yaml文件处理
- Golang之bytes.buffer学习笔记
- 深度学习之路, 从逻辑回归开始, 手写一个分类器.
- 【OpenCV学习笔记】之六 手写图像旋转函数---万丈高楼平地起
- TensorFlow学习笔记(一):手写数字识别之softmax回归
- TensorFlow学习笔记(四):手写数字识别之LSTM网络
- 手写一个HelloWorld,用命令行执行
- GoLang学习基础笔记
- Golang学习笔记//序
- Golang Log 学习笔记
- Golang学习笔记:常见问题
- Golang学习笔记
- Storm环境搭建和基本入门
- 将博客搬至CSDN
- Scala基础学习入门
- [置顶] freemarker+ITextRenderer 生成html转pdf
- Java和dubbo中的SPI机制学习
- golang学习笔记之手写一个执行器
- 文章标题
- SimpleDateFormat导致的多线程问题
- 一次压测情况下Solr部分性能调整
- nginx基本配置学习
- mysql 企业商用版下载
- 总结线上遇到的MySQL死锁问题
- java中的线程安全与锁优化
- 用ViewDragHelper自定义侧滑菜单——浅析源码解决与ScrollView的滑动冲突