-
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.
- Loading branch information
Showing
4 changed files
with
38 additions
and
37 deletions.
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 |
---|---|---|
@@ -1,41 +1,42 @@ | ||
# Tip #31 使用跳转标签让break和continue语句更简洁 | ||
|
||
> 原始链接: [Golang Tip #32: Scheduling functions after context cancellation with context.AfterFunc](https://twitter.com/func25/status/1762087461839364445) | ||
> | ||
在 [tip #30](https://colobu.com/gotips/030.html),我们学习了如何使一个Context在其Context停止时仍能继续运行: | ||
|
||
现在,让我们来看一下Go 1.21引入的一项新特性。 | ||
|
||
在 tip #30,我们已经知道如何在父 context 停止的时候让 context 继续下去 :https://twitter.com/func25/status/1761388781201174853 | ||
`context.AfterFunc`允许您设置一个回调函数`f`,在ctx结束后(无论因取消还是超时)在新的goroutine中运行。 | ||
|
||
现在让我看看在 Go1.21 引入的新特性 | ||
|
||
`context.AfterFunc` 可以让你设置一个回调函数 `f`,回调函数会在 `ctx` 结束后在它的上下文运行(无论是因为 `ctx` 被取消或者是超时) | ||
|
||
![](./images/032/1.png) | ||
|
||
该功能非常适合清理、记录日志或其类型的回收资源任务。 | ||
|
||
*回调函数什么时候执行?* | ||
该特性对于清理、日志记录或其他取消后的任务非常有用。 | ||
|
||
回调函数在一个新的 goroutine 中运行,该 goroutine 会在收到父 context 的 `ctx.done` 通道发出的信号后被触发 | ||
> “回调函数何时运行?” | ||
*如果 context 已经被取消了会发生什么?* | ||
回调函数在一个新的goroutine中运行,该goroutine在接收到父级上下文的ctx.done通道发送的信号后被触发。 | ||
|
||
回调函数会立刻执行,当然这发生在 go 协程里 | ||
> “如果上下文已经取消了怎么办?” | ||
这里有几个关键点: | ||
回调函数会立即运行,当然也是在一个新的`goroutine`中。 | ||
|
||
- 独立运行:,你可以在同一上下文中多次使用 AfterFunc 而不会出现任何问题,设置的每个任务都会独立运行。 | ||
- context结束时立刻执行:当你调用 AfterFunc 时,context被取消,它会在一个新的 go 协程中运行。 | ||
- 你可以取消计划中的函数,提供了一种结束机制(stop)可以结束运行中的回调函数 | ||
- 非阻塞:使用stop机制并不会等待回调函数结束,如果你希望主程序同步等待回调函数结束,你需要自己实现这个逻辑 | ||
以下是几个要点: | ||
|
||
我们来简单说下结束机制 `stop()`,它是 `AfterFunc` 的返回值 | ||
- 自行运行:您可以多次使用同一上下文调用`AfterFunc`而没有任何问题,您设置的每个任务都会各自独立运行。 | ||
- 如果上下文已完成则立即运行:如果在调用`AfterFunc`时`ctx`已结束,则它会立即在一个新的goroutine中启动`f`。 | ||
- 可以取消计划中的函数:它为您提供了一个`stop`函数,可以阻止f运行。 | ||
- 非阻塞:使用`stop`不会等待f完成,而是快速停止。如果您需要f和主线程工作保持同步,需要您自行安排。 | ||
接下来我们谈谈AfterFunc返回的stop()函数: | ||
|
||
![](./images/032/2.png) | ||
|
||
如果我们在上context 结束之前调用 stop(),而此时回调尚未运行(因此实际上,goroutine 尚未被触发),则 stopped 的值将为 true | ||
|
||
这意味着我们成功阻止了回调函数的运行。 | ||
如果我们尚未完成上下文且回调尚未运行(实际上,goroutine尚未被触发)时就调用stop(),那么stopped将为true。 | ||
|
||
如果 stopped 的值为false,这可能意味着其中之一: | ||
这意味着我们成功阻止了回调的运行。 | ||
|
||
- 回调函数启动了一个协程正在运行中 | ||
- 回调函数已经被停止了 | ||
如果stop()返回false,则可能意味着: | ||
- 函数f已在新的goroutine中开始运行。 | ||
- 函数`f`已被停止。 |
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