问题描述:
go 编程,实现高并发交替打印1234。
解答:
在 Go 中实现 高并发交替打印 1234 的需求,可以通过并发和同步机制(如 goroutine 和 channel)来协调多个协程的执行顺序,确保每次只打印一个数字,并按照 1 -> 2 -> 3 -> 4
的顺序循环进行。
✅ 1、实现目标
- 使用多个 goroutine 分别负责打印数字 1、2、3、4;
- 每个 goroutine 打印完后,触发下一个 goroutine;
- 通过
channel
实现顺序控制; - 可以指定打印的总次数;
- 整个程序在指定次数完成后优雅退出。
🛠 2、实现方案
我们将使用如下机制:
- 四个 channel 来控制执行顺序:
ch1
,ch2
,ch3
,ch4
; - 一个 done channel 用于通知所有 goroutine 退出;
- 一个共享计数器
count
来记录已完成的循环次数; - 每个 goroutine 在接收到自己的 channel 信号后打印数字,并传递信号给下一个;
- 主函数 初始化 channel 并启动 goroutine,最后等待所有 goroutine 完成。
🧩 3、示例代码
package main
import (
"fmt"
"sync"
)
func main() {
total := 3 // 总共打印 3 轮 1234
var wg sync.WaitGroup
ch1 := make(chan struct{})
ch2 := make(chan struct{})
ch3 := make(chan struct{})
ch4 := make(chan struct{})
done := make(chan struct{})
var mu sync.Mutex
count := 0
wg.Add(4)
// 打印 1 的 goroutine
go func() {
defer wg.Done()
for {
select {
case <-ch1:
fmt.Print("1")
ch2 <- struct{}{}
case <-done:
return
}
}
}()
// 打印 2 的 goroutine
go func() {
defer wg.Done()
for {
select {
case <-ch2:
fmt.Print("2")
ch3 <- struct{}{}
case <-done:
return
}
}
}()
// 打印 3 的 goroutine
go func() {
defer wg.Done()
for {
select {
case <-ch3:
fmt.Print("3")
ch4 <- struct{}{}
case <-done:
return
}
}
}()
// 打印 4 的 goroutine
go func() {
defer wg.Done()
for {
select {
case <-ch4:
fmt.Print("4")
mu.Lock()
count++
if count >= total {
close(done) // 结束所有 goroutine
} else {
ch1 <- struct{}{} // 触发下一轮打印
}
mu.Unlock()
case <-done:
return
}
}
}()
// 启动第一轮打印
ch1 <- struct{}{}
// 等待所有 goroutine 完成
wg.Wait()
fmt.Println() // 换行
}
🧪 4、示例输出
如果设置 total = 3
,程序将输出:
123412341234
📌 5、说明
- 使用
select
语句使每个 goroutine 能够响应 channel 或done
信号; - 使用
sync.Mutex
保护共享计数器count
; - 使用
done
channel 控制 goroutine 退出; - 使用
sync.WaitGroup
等待所有 goroutine 完成后再退出主程序; - 该设计具有良好的并发控制能力,适用于高并发环境下的顺序执行需求。
🔄 6、可扩展性
- 若需无限打印,可移除
count
和done
逻辑; - 若要支持动态控制停止,可使用
context.Context
替代done
; - 可扩展为打印任意长度的数字序列(如 123456789…)。
通过上述实现,我们不仅实现了高并发交替打印 1234,还确保了执行顺序和程序的健壮性。