mirror of
https://github.com/unknwon/the-way-to-go_ZH_CN.git
synced 2025-11-13 17:36:12 +08:00
@@ -2,7 +2,7 @@
|
||||
|
||||
`time` 包中有一些有趣的功能可以和通道组合使用。
|
||||
|
||||
其中就包含了 `time.Ticker` 结构体,这个对象以指定的时间间隔重复的向通道 C 发送时间值:
|
||||
其中就包含了 `time.Ticker` 结构体,这个对象以指定的时间间隔重复的向通道 `C` 发送时间值:
|
||||
|
||||
```go
|
||||
type Ticker struct {
|
||||
@@ -12,7 +12,7 @@ type Ticker struct {
|
||||
}
|
||||
```
|
||||
|
||||
时间间隔的单位是 ns(纳秒,int64),在工厂函数 `time.NewTicker` 中以 `Duration` 类型的参数传入:`func NewTicker(dur) *Ticker`。
|
||||
时间间隔的单位是 `ns`(纳秒,`int64`),在工厂函数 `time.NewTicker` 中以 `Duration` 类型的参数传入:`func NewTicker(dur) *Ticker`。
|
||||
|
||||
在协程周期性的执行一些事情(打印状态日志,输出,计算等等)的时候非常有用。
|
||||
|
||||
@@ -34,7 +34,7 @@ default: // no value ready to be received
|
||||
}
|
||||
```
|
||||
|
||||
`time.Tick()` 函数声明为 `Tick(d Duration) <-chan Time`,当你想返回一个通道而不必关闭它的时候这个函数非常有用:它以 d 为周期给返回的通道发送时间,d 是纳秒数。如果需要像下边的代码一样,限制处理频率(函数 `client.Call()` 是一个 RPC 调用,这里暂不赘述(参见第 [15.9](15.9.md) 节):
|
||||
`time.Tick()` 函数声明为 `Tick(d Duration) <-chan Time`,当你想返回一个通道而不必关闭它的时候这个函数非常有用:它以 `d` 为周期给返回的通道发送时间,`d` 是纳秒数。如果需要,像下边的代码一样,可以限制处理频率(函数 `client.Call()` 是一个 RPC 调用,这里暂不赘述(参见第 [15.9](15.9.md) 节)):
|
||||
|
||||
```go
|
||||
import "time"
|
||||
@@ -52,7 +52,7 @@ for req := range requests {
|
||||
|
||||
问题 14.1:扩展上边的代码,思考如何承载周期请求数的暴增(提示:使用带缓冲通道和计时器对象)。
|
||||
|
||||
定时器(Timer)结构体看上去和计时器(Ticker)结构体的确很像(构造为 `NewTimer(d Duration)`),但是它只发送一次时间,在 `Dration d` 之后。
|
||||
定时器 (`Timer`) 结构体看上去和计时器 (`Ticker`) 结构体的确很像(构造为 `NewTimer(d Duration)`),但是它只发送一次时间,在 `Dration d` 之后。
|
||||
|
||||
还有 `time.After(d)` 函数,声明如下:
|
||||
|
||||
@@ -111,7 +111,7 @@ tick.
|
||||
BOOM!
|
||||
```
|
||||
|
||||
习惯用法:简单超时模式
|
||||
**习惯用法:简单超时模式**
|
||||
|
||||
要从通道 `ch` 中接收数据,但是最多等待 1 秒。先创建一个信号通道,然后启动一个 `lambda` 协程,协程在给通道发送数据之前是休眠的:
|
||||
|
||||
@@ -137,7 +137,7 @@ select {
|
||||
|
||||
第二种形式:取消耗时很长的同步调用
|
||||
|
||||
也可以使用 `time.After()` 函数替换 `timeout-channel`。可以在 `select` 中通过 `time.After()` 发送的超时信号来停止协程的执行。以下代码,在 `timeoutNs` 纳秒后执行 `select` 的 `timeout` 分支后,执行`client.Call` 的协程也随之结束,不会给通道 `ch` 返回值:
|
||||
也可以使用 `time.After()` 函数替换 `timeout-channel`。可以在 `select` 中通过 `time.After()` 发送的超时信号来停止协程的执行。以下代码,在 `timeoutNs` 纳秒后执行 `select` 的 `timeout` 分支后,执行 `client.Call` 的协程也随之结束,不会给通道 `ch` 返回值:
|
||||
|
||||
```go
|
||||
ch := make(chan error, 1)
|
||||
@@ -151,7 +151,7 @@ case <-time.After(timeoutNs):
|
||||
}
|
||||
```
|
||||
|
||||
注意缓冲大小设置为 1 是必要的,可以避免协程死锁以及确保超时的通道可以被垃圾回收。此外,需要注意在有多个 `case` 符合条件时, `select` 对 `case` 的选择是伪随机的,如果上面的代码稍作修改如下,则 `select` 语句可能不会在定时器超时信号到来时立刻选中 `time.After(timeoutNs)` 对应的 `case`,因此协程可能不会严格按照定时器设置的时间结束。
|
||||
注意缓冲大小设置为 `1` 是必要的,可以避免协程死锁以及确保超时的通道可以被垃圾回收。此外,需要注意在有多个 `case` 符合条件时, `select` 对 `case` 的选择是伪随机的,如果上面的代码稍作修改如下,则 `select` 语句可能不会在定时器超时信号到来时立刻选中 `time.After(timeoutNs)` 对应的 `case`,因此协程可能不会严格按照定时器设置的时间结束。
|
||||
|
||||
```go
|
||||
ch := make(chan int, 1)
|
||||
|
||||
Reference in New Issue
Block a user