Go并发实战:5协程随机数求和Go语言的并发编程有多强?这次我们用一个实战案例来告诉你!想象一下:5个协程同时生成随机数,扔进一个通道,另一个协程实时接住、求和,最后输出结果。听起来简单?但要做到高效、无阻塞,还得空间复杂度O(1),可没那么容易。本文带你一步步实现这个任务,代码全公开,运行结果一
Go语言的并发编程有多强?这次我们用一个实战案例来告诉你!想象一下:5个协程同时生成随机数,扔进一个通道,另一个协程实时接住、求和,最后输出结果。听起来简单?但要做到高效、无阻塞,还得空间复杂度O(1),可没那么容易。本文带你一步步实现这个任务,代码全公开,运行结果一目了然。无论你是Go新手还是老司机,这篇干货都能让你有所收获!
本文通过一个Go并发编程案例,展示了如何用5个生产者协程并发生成随机数量的随机数(0-99),并由1个消费者协程实时读取并求和。程序巧妙利用无缓冲通道和sync.WaitGroup,避免time.Sleep,确保空间复杂度O(1)。代码实现简洁高效,运行过程清晰可见,最终输出所有随机数的总和。适合想快速上手Go并发或优化代码的开发者参考。
5个协程并发,发送随机数量的随机数到一个channel,另外一个协程从channel读取数据,不能用time.sleep,求和并打印结果,要求空间复杂度为O(1)。
package main
import (
"fmt"
"math/rand"
"sync"
)
// 5个协程并发,发送随机数量的随机数到一个channel,另外一个协程从channel读取数据,不能用time.sleep,求和并打印结果,要求空间复杂度为O(1)。
func producer(id int, ch chan<- int, wg *sync.WaitGroup) {
defer wg.Done()
count := rand.Intn(10) + 1 // 随机1-10个数
for i := 0; i < count; i++ {
num := rand.Intn(100) // 随机0-99的数
ch <- num
fmt.Printf("Producer %d sent: %d\n", id, num)
}
}
func consumer(ch <-chan int, done chan<- bool) {
sum := 0
for num := range ch {
sum += num
fmt.Printf("Consumer received: %d, current sum: %d\n", num, sum)
}
fmt.Println("Final sum:", sum)
done <- true
}
func main() {
const producerCount = 5
ch := make(chan int)
var wg sync.WaitGroup
done := make(chan bool)
// 启动消费者
go consumer(ch, done)
// 启动生产者
wg.Add(producerCount)
for i := 0; i < producerCount; i++ {
go producer(i, ch, &wg)
}
// 等待所有生产者完成
go func() {
wg.Wait()
close(ch) // 关闭channel通知消费者
}()
// 等待消费者完成
<-done
}
golearn on main via 🐹 v1.24.1 via 🅒 base took 4.2s
➜ go run main.go
Producer 1 sent: 41
Consumer received: 41, current sum: 41
Consumer received: 57, current sum: 98
Consumer received: 56, current sum: 154
Consumer received: 77, current sum: 231
Producer 0 sent: 57
Consumer received: 68, current sum: 299
Consumer received: 34, current sum: 333
Producer 0 sent: 34
Producer 0 sent: 88
Producer 4 sent: 68
Consumer received: 88, current sum: 421
Consumer received: 53, current sum: 474
Consumer received: 56, current sum: 530
Producer 4 sent: 56
Producer 4 sent: 91
Producer 0 sent: 53
Producer 3 sent: 77
Producer 2 sent: 56
Consumer received: 91, current sum: 621
Consumer received: 9, current sum: 630
Consumer received: 52, current sum: 682
Consumer received: 23, current sum: 705
Consumer received: 63, current sum: 768
Producer 2 sent: 63
Producer 2 sent: 98
Consumer received: 98, current sum: 866
Consumer received: 2, current sum: 868
Producer 2 sent: 2
Producer 2 sent: 87
Consumer received: 87, current sum: 955
Consumer received: 90, current sum: 1045
Producer 0 sent: 52
Producer 0 sent: 62
Producer 3 sent: 23
Producer 2 sent: 90
Consumer received: 62, current sum: 1107
Consumer received: 68, current sum: 1175
Consumer received: 65, current sum: 1240
Producer 4 sent: 9
Producer 4 sent: 70
Producer 3 sent: 68
Producer 2 sent: 65
Consumer received: 70, current sum: 1310
Consumer received: 14, current sum: 1324
Consumer received: 97, current sum: 1421
Producer 3 sent: 14
Producer 3 sent: 40
Consumer received: 40, current sum: 1461
Consumer received: 14, current sum: 1475
Producer 2 sent: 97
Producer 2 sent: 90
Consumer received: 90, current sum: 1565
Producer 3 sent: 14
Producer 3 sent: 70
Consumer received: 70, current sum: 1635
Consumer received: 33, current sum: 1668
Producer 3 sent: 33
Producer 3 sent: 72
Consumer received: 72, current sum: 1740
Final sum: 1740
这次实战让我们见识了Go并发的威力:5个协程齐发随机数,1个协程稳稳接招,求和结果瞬间呈现。借助通道和sync.WaitGroup,我们不仅实现了任务,还保持了O(1)的空间效率。这样的设计简单却实用,完美展现了Go在并发场景下的优势。想提升编程功力?不妨动手跑跑代码,感受Go的魅力吧!下次,我们可以试试更复杂的并发挑战,你准备好了吗?
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!