当前位置: 首页 > news >正文

南昌模板建站定制网站廊坊seo关键词排名

南昌模板建站定制网站,廊坊seo关键词排名,中国一级爱做电影网站,旅游景区网站源码goroutine的数量上限是1048575吗? 正常项目,协程数量超过十万就需要引起重视。如果有上百万goroutine,一般是有问题的。 但并不是说协程数量的上限是100多w 1048575的来自类似如下的demo代码: package mainimport ( "fmt" "ma…

goroutine的数量上限是1048575吗?


正常项目,协程数量超过十万就需要引起重视。如果有上百万goroutine,一般是有问题的。

但并不是说协程数量的上限是100多w

1048575的来自类似如下的demo代码:

package main

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

// https://zhuanlan.zhihu.com/p/568151296
func main() {

 maxCount := math.MaxInt64
 for i := 0; i < maxCount; i++ {
  go func(i int) {
   fmt.Printf("i is: %d,goroutine num: %d\n", i, runtime.NumGoroutine())

   // 模拟各种耗时较长的业务逻辑
   time.Sleep(10 * time.Second)

  }(i)
 }
}

执行后,很快报错

alt

panic: too many concurrent operations on a single file or socket (max 1048575)

但这个是因为fmt.Printf导致的:

对单个file/socket的并发操作数超过了系统上限,这个是标准输出造成的,具体一点,就是文件句柄数量达到限制

如下例子,去掉fmt:

package main

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

func main() {

 maxCount := math.MaxInt64
 for i := 0; i < maxCount; i++ {
  go func(i int) {
   // 模拟各种耗时较长的业务逻辑
   //time.Sleep(10 * time.Hour)
   time.Sleep(15 * time.Second)
   if i > 1300_0000 {
    //if runtime.NumGoroutine() > 1000_0000 {
    fmt.Println("当前协程数:", runtime.NumGoroutine())
   }

  }(i)
 }
}
alt

实际同一时间可以出现1000w的goroutine,可见goroutine的理论上限绝对不止100w

或者如下:

package main

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

func main() {

 maxCount := math.MaxInt64
 for i := 0; i < maxCount; i++ {
  go func(i int) {
   // 模拟各种耗时较长的业务逻辑
   //time.Sleep(10 * time.Hour)
   time.Sleep(15 * time.Second)
   //if i > 1300_0000 {
   if runtime.NumGoroutine() > 800_0000 {
    fmt.Println("当前协程数:", runtime.NumGoroutine())
   }

  }(i)
 }
}
alt
panic: too many concurrent operations on a single file or socket (max 1048575)

goroutine 1231546 [running]:
internal/poll.(*fdMutex).rwlock(0x140000a20600x20?)
        /Users/fliter/.g/go/src/internal/poll/fd_mutex.go:147 +0x134
internal/poll.(*FD).writeLock(...)
        /Users/fliter/.g/go/src/internal/poll/fd_mutex.go:239
internal/poll.(*FD).Write(0x140000a2060, {0x14635532bc00x190x20})
        /Users/fliter/.g/go/src/internal/poll/fd_unix.go:370 +0x48
os.(*File).write(...)
        /Users/fliter/.g/go/src/os/file_posix.go:48
os.(*File).Write(0x140000a0008, {0x14635532bc0?, 0x190x10412e25c?})
        /Users/fliter/.g/go/src/os/file.go:175 +0x60
fmt.Fprintln({0x104168cf80x140000a0008}, {0x140bde92f880x20x2})
        /Users/fliter/.g/go/src/fmt/print.go:285 +0x74
fmt.Println(...)
        /Users/fliter/.g/go/src/fmt/print.go:294
main.main.func1(0x0?)
        /Users/fliter/go/src/shuang/0000/goNum.go:20 +0x150
created by main.main
        /Users/fliter/go/src/shuang/0000/goNum.go:14 +0x54
exit status 2

比较奇怪的是,如果将模拟各种耗时较长的业务逻辑time.Sleep(15 * time.Second)改为time.Sleep(10 * time.Hour),最终会因为内存过高而signal: killed。但此时goroutine数量不够多,触发不了if里面的fmt逻辑,故而不会出现panic: too many concurrent operations on a single file or socket (max 1048575)

alt

(而休眠10几s的代码,内存到不了这么大,就已经因为fmt的问题panic了)

alt

控制方式


使用有缓冲的channel,限制并发的协程数量


make(chan struct{}, 300) 创建缓冲区大小为 300 的 channel,在没有被接收的情况下,至多发送 300 个消息则被阻塞。

开启协程前,调用 ch <- struct{}{},若缓存区满,则阻塞。 协程任务结束,调用 <-ch 释放缓冲区。

// 通过channel来控制并发数

package main

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

func main() {

 ch := make(chan struct{}, 300)
 maxCount := math.MaxInt64
 for i := 0; i < maxCount; i++ {
  ch <- struct{}{}
  go func(i int) {
   //fmt.Printf("i is: %d,go func num: %d\n", i, runtime.NumGoroutine())

   // 模拟各种耗时较长的业务逻辑
   //time.Sleep(10 * time.Hour)
   time.Sleep(15 * time.Second)
   //if i > 1000_0000 {
   //if runtime.NumGoroutine() > 1000_0000 {
   fmt.Println("当前协程数:", runtime.NumGoroutine())
   //}

   //读取channel数据
   <-ch

  }(i)
 }
}
当前协程数: 301
当前协程数: 301
当前协程数: 301
当前协程数: 301
当前协程数: 301
当前协程数: 301
当前协程数: 301
当前协程数: 301
当前协程数: 301
...

同时只有301个协程(每15s,处理301个;限制太少,会大大增加程序执行完成需要的时间,具体限制多少,需要权衡,太大太小可能都有问题)


更多参考:

如何控制golang协程的并发数量问题[1]

golang实现并发数控制的方法[2]

golang控制并发数[3]

Golang的并发控制[4]


即所谓的

无缓冲的channel可以当成阻塞锁来使用 (Go用两个协程交替打印100以内的奇偶数)

有缓冲的channel通常可以用来控制goroutine的数量


来,控制一下 goroutine 的并发数量[5]

还有通过协程池,信号量等方式,可参考 【警惕】请勿滥用goroutine[6]

aceld-Go是否可以无限go?如何限定数量?[7]

参考资料

[1]

如何控制golang协程的并发数量问题: http://www.manongjc.com/detail/62-ixfkirkdenvuohr.html

[2]

golang实现并发数控制的方法: http://www.qb5200.com/article/327027.html

[3]

golang控制并发数: https://blog.csdn.net/weixin_38155824/article/details/128240704

[4]

Golang的并发控制: https://blog.csdn.net/LINZEYU666/article/details/123020597

[5]

来,控制一下 goroutine 的并发数量: https://eddycjy.gitbook.io/golang/di-1-ke-za-tan/control-goroutine

[6]

【警惕】请勿滥用goroutine: https://juejin.cn/post/6999807716482875422#heading-5

[7]

aceld-Go是否可以无限go?如何限定数量?: https://github.com/catandcoder/golang/blob/main/4%E3%80%81Go%E6%98%AF%E5%90%A6%E5%8F%AF%E4%BB%A5%E6%97%A0%E9%99%90go%EF%BC%9F%E5%A6%82%E4%BD%95%E9%99%90%E5%AE%9A%E6%95%B0%E9%87%8F%EF%BC%9F.md

本文由 mdnice 多平台发布

http://www.15wanjia.com/news/51854.html

相关文章:

  • 传奇网站发布网徐州seo顾问
  • 网站推广公司招聘在线生成网页网站
  • 涪陵网站制作热门搜索
  • 企业建设网站的母的seo优化官网
  • 电脑手机自适应网站的建设美食软文300范例
  • 网站建设作用 名词解释seo综合优化公司
  • 网站开发环境是什么什么是市场营销
  • 网站的回到顶部怎么做重庆seo整站优化效果
  • 什么样的网站需要改版aso优化注意什么
  • 网站为什么要seo?站长工具seo综合查询怎么用
  • 邢台做网站公司西安百度seo
  • 京津冀协同发展交通一体化规划seo引擎优化平台培训
  • 哪个网站做美食自媒体更好seo优化操作
  • 长沙百度搜索网站排名关键词拓展工具有哪些
  • 灰色色调的网站中国十大搜索引擎排名最新
  • 广州专业网站建设性价比高seo是付费还是免费推广
  • 百度小程序可以根据网站的要求做seo站长工具
  • 找阿里巴巴购买做网站的软件广州王牌seo
  • 钟祥网站建设网页搜索快捷键
  • 北京网站建设公司哪家好商城网站建设
  • 上海网站建设最好的公司排名seo霸屏软件
  • 祁东网站开发怎么利用互联网推广
  • 网站反链接是什么意思seo主要做什么工作
  • 网站上职业学校排名 该怎么做长沙网络公司营销推广
  • 百万综合文字论文网址的内容济南seo外包公司
  • 网站建设对电子商务的意义火星培训机构收费明细
  • 手机app开发制作报价北京如何优化搜索引擎
  • 阿里巴巴网站怎么做全屏大图怎么建立网站快捷方式
  • 做网站需要注册什么类型的公司今天宣布疫情最新消息
  • wap网站开发视频教程网站搭建费用