-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #160 from LinPr/master
Golang Tip #32: Scheduling functions after context cancellation with context.AfterFunc
- Loading branch information
Showing
4 changed files
with
42 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
> 原始链接: [Golang Tip #32: Scheduling functions after context cancellation with context.AfterFunc](https://twitter.com/func25/status/1762087461839364445) | ||
|
||
|
||
在 tip #30,我们已经知道如何在父 context 停止的时候让 context 继续下去 :https://twitter.com/func25/status/1761388781201174853 | ||
|
||
现在让我看看在 Go1.21 引入的新特性 | ||
|
||
`context.AfterFunc` 可以让你设置一个回调函数 `f`,回调函数会在 `ctx` 结束后在它的上下文运行(无论是因为 `ctx` 被取消或者是超时) | ||
|
||
![](./images/032/1.png) | ||
|
||
该功能非常适合清理、记录日志或其类型的回收资源任务。 | ||
|
||
*回调函数什么时候执行?* | ||
|
||
回调函数在一个新的 goroutine 中运行,该 goroutine 会在收到父 context 的 `ctx.done` 通道发出的信号后被触发 | ||
|
||
*如果 context 已经被取消了会发生什么?* | ||
|
||
回调函数会立刻执行,当然这发生在 go 协程里 | ||
|
||
这里有几个关键点: | ||
|
||
- 独立运行:,你可以在同一上下文中多次使用 AfterFunc 而不会出现任何问题,设置的每个任务都会独立运行。 | ||
- context结束时立刻执行:当你调用 AfterFunc 时,context被取消,它会在一个新的 go 协程中运行。 | ||
- 你可以取消计划中的函数,提供了一种结束机制(stop)可以结束运行中的回调函数 | ||
- 非阻塞:使用stop机制并不会等待回调函数结束,如果你希望主程序同步等待回调函数结束,你需要自己实现这个逻辑 | ||
|
||
我们来简单说下结束机制 `stop()`,它是 `AfterFunc` 的返回值 | ||
|
||
![](./images/032/2.png) | ||
|
||
如果我们在上context 结束之前调用 stop(),而此时回调尚未运行(因此实际上,goroutine 尚未被触发),则 stopped 的值将为 true | ||
|
||
这意味着我们成功阻止了回调函数的运行。 | ||
|
||
如果 stopped 的值为false,这可能意味着其中之一: | ||
|
||
- 回调函数启动了一个协程正在运行中 | ||
- 回调函数已经被停止了 |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.