Skip to main content

chan time.Tick 并行 or 并发

每 200ms 自动往通道发信息?

 limiter := time.Tick(200 * time.Millisecond)

time.Tick 的特点是创建一个定时器通道,每隔指定时间发送一个时间值。下面是它的一些特点和行为:

特点

  1. 固定间隔:每隔指定的时间间隔发送一个时间值。
  2. 简单易用:用于简单的定时任务。
  3. 阻塞行为:接收操作会阻塞,直到通道中有值可读。

阻塞

当你使用 <-limiter 时,程序会阻塞在这里,直到从通道中接收到一个值。这意味着在接收到值之前,后续的代码不会执行。

各做各的

如果你有多个 goroutine,它们可以各自从同一个 time.Tick 通道中读取,而不会相互影响。不过,这样会导致它们共享同一个节奏。如果需要独立的定时,可以为每个 goroutine 创建自己的定时器。

注意事项

  • 内存泄漏time.Tick 会一直运行,直到程序退出。如果不再需要定时器,使用 time.NewTicker 并手动停止它更为合适。
  • 精度限制:由于 Go 的调度器和系统的限制,时间间隔可能不完全精确。

示例

package main

import (
"fmt"
"time"
)

func worker(id int, limiter <-chan time.Time) {
for i := 0; i < 3; i++ {
<-limiter
fmt.Printf("Worker %d: Action %d at %s\n", id, i, time.Now())
}
}

func main() {
limiter := time.Tick(200 * time.Millisecond)

for i := 0; i < 2; i++ {
go worker(i, limiter)
}

time.Sleep(2 * time.Second) // 等待所有操作完成
}

在这个例子中,两个 worker goroutine 各自从同一个 limiter 通道读取时间值,按照固定的节奏执行任务。

并行 or 并发

这种情况属于并发。

并发与并行的区别

  • 并发:指程序可以处理多个任务,任务之间可能交替进行。它关注的是任务的调度和管理。
  • 并行:指多个任务同时执行,通常需要多核处理器支持。

在你的例子中,多个 goroutine 在同一时间段内被调度执行,但它们未必同时运行在不同的处理器核心上。Go 的调度器负责在单个或多个核心上交替执行这些 goroutine,所以是并发的。要实现真正的并行,需要在多核系统上运行,且 Go 的调度器会将 goroutine 分配到不同的核心上。