展开目录
golang 限制goroutine并行个数
golanggoroutine
X
陈尼玛的博客
记录开发生涯的踩坑经历,用时间来验证成长
加载中

踩到了goroutine暴增导致导致服务器死机的坑,因此我尝试限制goroutine并行个数。基本思路是用channel来控制并行个数和最大队列个数。

不做限制的代码是这样的:

package main

import (
  "time"
  "fmt"
  "runtime"
)


func main(){

  // 定义一个运行时间为1秒的方法
  oneSecond := func(i int){
    time.Sleep(1e9)
    fmt.Println(i)
  }

  for i:=0; i<10 ;i++ {
    go oneSecond(i)
  }

  for runtime.NumGoroutine()>1 {
    time.Sleep(1e9)
  }
}

上述代码,运行结果是所有内容一起输出,因此是所有goroutine同时运行的。

channel的限制原理是,定义一个n长度的chan,如果能向chan推入内容,则运行代码,否则阻塞。下面是一个简易的封装:

package main

import (
  "time"
  "fmt"
  "runtime"
)
func main(){

  // 定义一个运行时间为1秒的方法
  oneSecond := func(i int){
    time.Sleep(1e9)
    fmt.Println(i)
  }

  n := 3 // n限制一次可以运行多少个
  s := make(chan bool,n)
  for i:=0; i<10 ;i++ {
    s<-true
    go func(i int){
      oneSecond(i)
      <-s
    }(i)
  }

  for runtime.NumGoroutine()>1 {
    time.Sleep(1e9)
  }
}

这次的输出结果是每次输出n个数字,直到运行结束。

最后为了使用方便,我对这个限制进一步封装:

package main

import (
  "time"
  "fmt"
  "runtime"
)

/********  封装部分开始  *******/
type Gos struct{
  s chan bool
  f chan func() // 待执行的func队列
}
func NewGos(n int,m int)*Gos{
  g := new(Gos)
  g.s = make(chan bool,n) // 限制并行的goroutine最多n个,超过则本次func会排队
  g.f = make(chan func(),m) // 限制排队的func最多m个,超过则外部调用的地方会阻塞
  return g
}

func(g *Gos) Run(x func()){
  select{
  case g.s<-true: go func(){
    x()
    <-g.s
    select{
      default:
      case x := <-g.f: g.Run(x)
    }
  }()
  default: g.f<-x
  }
}
/********  封装部分结束  *******/

func main(){

  // 定义一个运行时间为1秒的方法
  oneSecond := func(i int){
    time.Sleep(1e9)
    fmt.Println(i)
  }

  s := NewGos(3,10)
  for i:=0; i<10 ;i++ {
    func(i int){
      s.Run(func(){ oneSecond(i) })
    }(i)
  }

  for runtime.NumGoroutine()>1 {
    time.Sleep(1e9)
  }
}

以上

相关文档

暂无

随便看看

  1. cnpm 立即同步

  2. sass变量和继承类写法

  3. ios13 vpn 能连接但不能传数据问题解决

  4. nodejs socks5

  5. 树莓派实现用pi用户自动登录

  6. nodejs俄罗斯方块

  7. mongodb 批量修改字段语句

  8. npm设置仓库地址和代理

  9. dd备份/还原

  10. cdn资源列表

  11. git记住/删除账号密码

  12. git 设置代理服务器

  13. ssl 证书生成方式

  14. mongodb2.4 添加用户

  15. 树莓派配置收发邮件

  16. 猴子选大王算法问题

  17. youku电脑版跳过广告代码

  18. html表格导出csv文件并下载

畅言模块加载中