

Go语言:调度间隔用哪个好?time.Sleep v.s. time.After
source link: https://www.tuicool.com/articles/BZJzQz7
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Go编程中循环调度任务的执行间隔我们通常采用 time.Sleep或time.After来实现。
写法1:
go func(ctx context.Context) { for { select { case <-ctx.Done(): fmt.Println("Cancelled", time.Now()) wg.Done() return default: time.Sleep(time.Second * 10) fmt.Println("Invoked", time.Now()) } } }(ctx)
写法2:
go func(ctx context.Context) { for { select { case <-ctx.Done(): fmt.Println("Cancelled", time.Now()) wg.Done() return case <-time.After(time.Second * 10): fmt.Println("Invoked", time.Now()) } } }(ctx)
这两种方式一样吗?那种方式更好呢? 以上两种写法,都可以满足需求。那么是否这两种写法是等效的呢? 当然不是,为了更好的说明它们的差别,请运行下面的这两段测试代码:
var wg sync.WaitGroup func cancelTaskAfter(interval time.Duration, cancel context.CancelFunc) { go func(cancel context.CancelFunc) { time.Sleep(interval) fmt.Println("Cancell task", time.Now()) cancel() wg.Done() }(cancel) } func TestTimerTask1(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) wg.Add(1) cancelTaskAfter(time.Second*25, cancel) wg.Add(1) go func(ctx context.Context) { for { select { case <-ctx.Done(): fmt.Println("Cancelled", time.Now()) wg.Done() return default: time.Sleep(time.Second * 10) fmt.Println("Invoked", time.Now()) } } }(ctx) wg.Wait() } func TestTimerTask2(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) wg.Add(1) cancelTaskAfter(time.Second*25, cancel) wg.Add(1) go func(ctx context.Context) { for { select { case <-ctx.Done(): fmt.Println("Cancelled", time.Now()) wg.Done() return case <-time.After(time.Second * 10): fmt.Println("Invoked", time.Now()) } } }(ctx) wg.Wait() }
也许看到这,你大概已经知道这两种写法的不同了。
以下是输出结果
=== RUN TestTimerTask1 Invoked 2019-09-22 17:12:07.055392 +0800 CST m=+35.007752073 Invoked 2019-09-22 17:12:17.057073 +0800 CST m=+45.009375450 Cancell task 2019-09-22 17:12:22.051311 +0800 CST m=+50.003583680 Invoked 2019-09-22 17:12:27.060766 +0800 CST m=+55.013010382 Cancelled 2019-09-22 17:12:27.060804 +0800 CST m=+55.013048342 --- PASS: TestTimerTask1 (30.01s)
=== RUN TestTimerTask2 Invoked 2019-09-22 17:11:42.049262 +0800 CST m=+10.001766181 Invoked 2019-09-22 17:11:52.053054 +0800 CST m=+20.005500478 Cancell task 2019-09-22 17:11:57.050145 +0800 CST m=+25.002563035 Cancelled 2019-09-22 17:11:57.05041 +0800 CST m=+25.002827648 --- PASS: TestTimerTask2 (25.00s)
采用Sleep来实现间隔的时候,如果cancel调用后任务协程正好处于sleep过程中,这时任务是无法被及时取消的。
小结 如果你需要任务能够被及时的取消,那你应该采用time.After来控制调用的间隔。
更多知识,欢迎订阅学习 《Go 语言入门到实战》
Recommend
-
79
-
10
[ML Notes] SVM:软间隔 Author: nex3z 2021-03-14 Contents [
-
8
间隔记忆工具:Anki 我的 Evernote 约有 3000 条笔记,有3个大分类:医学、产品、编程。为了对抗遗忘,需要经常分享这些知识给其他人,也要隔...
-
4
0代码隐藏GroupedTableView上边多余的间隔2015年4月15日实现诸如支付宝的 “探索” 页面时,最简单的方案是在 Storyboard 中来一个静态 Grouped UITableViewController,把各个 Cell 中的元素摆好就行了
-
5
Gavin 亲笔:Kusama 网络将进行 5 次拍卖,每次间隔 7 天PolkaWorld2021-05-18热度: 19383升级为statemine之后就开始拍卖!
-
17
Gavin Wood:Kusama 平行链插槽将进行 5 次拍卖,每次间隔 7 天_区块链资讯_链向财经Gavin Wood:Kusama 平行链插槽将进行 5 次拍卖,每次间隔 7 天来源:PolkaWorld撰文:Gavin Wood,波卡创始人...
-
6
Gavin亲笔:Kusama网络将进行5次拍卖,每次间隔7天 polkaworld 2021-05-18 14:56 摘要: Polkadot 的阶段上线即将进入另一...
-
9
欧科云链OKLink:比特币出块间隔达到18年以来最高水平 - 律动BlockBeats 律动 BlockBeats 消息,6 月 28 日,据欧科云链 OKLink 数据显示,由于近期网络哈希率持续下降,比特币的出块间隔时间大幅上升。6 月 27 日的出块间隔均值为 1198.18 秒,创下 18 年...
-
13
麻省理工科技评论-全球首个穿刺房间隔封堵器问世!为心脏房缺手术留出“微创通道”全球首个穿刺房间隔封堵器问世!为心脏房缺手术留出“微创通道”据《中国心血管报告》,中国先心病患者在 700 万 - 750 万左右,其发病率约为 0.8%,并以 12...
-
77
README.md ...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK