七叶笔记 » golang编程 » Go 系列8: 通过channel控制协程并发数量之核心特性

Go 系列8: 通过channel控制协程并发数量之核心特性

  1. go 高并发
  2. 并发控制
  3. 性能和稳定性的平衡艺术

什么是并发处理的数量

大家理解一下Goroutine 协程为轻量级的线程。 就是可有并发处理逻辑的最小单元。 理解多个 协程同时并发处理逻辑只要

for i:=0 ; i<=n; i++ {

go func() {

// 并发处理的逻辑

}()

}

上面就是n个协程同时并发处理逻辑。 在go中非常方便!。

为什么要控制并发处理的协程数量

上面说了非常方便多开几个协程。那么问题来了,如果不控制并发数量。我们举个例子,并发使用网络登陆同一个ftp server. 那么很快就会超过限制。而出现问题。 简单点说就是控制一下最大并发处理的协程的数量

怎么控制并发数量

控制 Goroutine 的数量

先看不控制并发的方法

func main() {

jobsCount := 10

group := sync.WaitGroup{}

for i := 0; i < jobsCount; i++ {

group.Add(1)

go func(i int) {

defer group.Done() // defer 保证函数退出前执行

fmt.Printf(“job %d!\n”, i)

jobWork() // 这里是一个同步的长时间的方法就是job

}(i)

fmt.Printf(“index: %d,goroutine Num: %d \n”, i, runtime .NumGoroutine())

}

group.Wait()

fmt.Println(“done!”)

}

输出结果:

ndex: 0,goroutine Num: 2

index: 1,goroutine Num: 3

index: 2,goroutine Num: 4

index: 3,goroutine Num: 5

index: 4,goroutine Num: 6

index: 5,goroutine Num: 7

index: 6,goroutine Num: 8

index: 7,goroutine Num: 9

index: 8,goroutine Num: 10

index: 9,goroutine Num: 11

job 9

job 0!

job 1!

job 2!

job 3!

job 4!

job 5!

job 6!

job 7!

job 8!

done!

控制并发数量的方法

注意,下面的代码控制最多4个并发协程同时处理! 4个4个4个不是n个哦

func main() {

jobsCount := 10

group := sync.WaitGroup{}

var jobsChan = make(chan int, 4)

// a) 协程1 生成指定数目的 goroutine,每个 goroutine 消费 jobsChan 中的数据

poolCount := 4

for i := 0; i < poolCount; i++ {

go func() {

for j := range jobsChan {

fmt.Printf(“hello %d\n”, j)

time.Sleep(time.Second)

group.Done()

}

}()

}

// b) 把 job 依次推送到 jobsChan 供 goroutine 消费

for i := 0; i < jobsCount; i++ {

jobsChan <- i

group.Add(1)

fmt.Printf(“index: %d,goroutine Num: %d\n”, i, runtime.NumGoroutine())

}

group.Wait()

fmt.Println(“done!”)

}

输出结果:

index: 0,goroutine Num: 5

index: 1,goroutine Num: 5

index: 2,goroutine Num: 5

index: 3,goroutine Num: 5

hello 0

hello 1

hello 2

hello 3

index: 4,goroutine Num: 5

index: 5,goroutine Num: 5

index: 6,goroutine Num: 5

index: 7,goroutine Num: 5

hello 4

hello 5

hello 6

hello 7

index: 8,goroutine Num: 5

index: 9,goroutine Num: 5

hello 8

hello 9

done!

理解控制方法的核心

就是将所有要处理的协成先入队。(有缓冲 channel )

在通过channel等待来实现并发的控制。

结论及反思扩展

理解之后发现好简单吧。这就是会了不难,难了不会。

老子道德经说: 福祸互为根生。对于go并发来说,我的理解就是

太快了,就不稳定。

太稳定了,(不并发)就不快。 这两者是可有互相转化的。

高并发好,快。

并发太高,系统受不了,又问题。 控制并发数,稳。

总之:在实际中还要根据系统的硬件设施。比如内存,iO,网络。等资源。进行一个动态的配置调试。 找到一个最佳平衡点。

!又快,又稳!

相关文章