Golang创建定时程序
前两天用Golang手写MapReduce框架时,遇到这样一个问题:
worker可能随时crash,那么coordinator分配给worker的任务不能无限等待worker的回复,因此需要给每个分配出去的任务设置timeout,也就是需要一个定时程序清理crash/太慢的worker的任务。
Golang对并发的原生支持是比较好的,直观而言,只需要在某个goroutine里等待timeout,然后重置这个任务即可。这里我们用“更像Golang”的方法来完成这个任务。
Golang time.Timer
time.Timer
是Golang标准库中提供的定时器。用如下代码可以创建一个新定时器(定时10秒):
1 | timer := time.NewTimer(time.Second * 10) |
Timer
有一个成员C
,类型是chan Time
的channel,根据官方文档:
The Timer type represents a single event. When the Timer expires, the current time will be sent on C, unless the Timer was created by AfterFunc. A Timer must be created with NewTimer or AfterFunc.
可见如果用上面的NewTimer
方法指定计时,那么Timer
到期后,会给C
发送时间。
再注意到Golang中channel是会阻塞的,我们可以用这个方法判断是否到时。
定时程序
首先在调用者函数中创建定时器Timer
,接着启动一个goroutine来等候Timer
的信号,这时调用者函数可以继续做其他工作。
1 | package main |
上面这段程序输出如下,每句still working...
输出间隔1秒:
1 | $ go run timer.go |