[场景实战]GO交替打印数字

问题描述:

go 编程,实现高并发交替打印1234。

解答:

在 Go 中实现 高并发交替打印 1234 的需求,可以通过并发和同步机制(如 goroutine 和 channel)来协调多个协程的执行顺序,确保每次只打印一个数字,并按照 1 -> 2 -> 3 -> 4 的顺序循环进行。

✅ 1、实现目标

  • 使用多个 goroutine 分别负责打印数字 1、2、3、4;
  • 每个 goroutine 打印完后,触发下一个 goroutine;
  • 通过 channel 实现顺序控制;
  • 可以指定打印的总次数;
  • 整个程序在指定次数完成后优雅退出。

🛠 2、实现方案

我们将使用如下机制:

  1. 四个 channel 来控制执行顺序:ch1, ch2, ch3, ch4
  2. 一个 done channel 用于通知所有 goroutine 退出;
  3. 一个共享计数器 count 来记录已完成的循环次数;
  4. 每个 goroutine 在接收到自己的 channel 信号后打印数字,并传递信号给下一个;
  5. 主函数 初始化 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、可扩展性

  • 若需无限打印,可移除 countdone 逻辑;
  • 若要支持动态控制停止,可使用 context.Context 替代 done
  • 可扩展为打印任意长度的数字序列(如 123456789…)。

通过上述实现,我们不仅实现了高并发交替打印 1234,还确保了执行顺序和程序的健壮性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值