解释下这段使用 Go 通道的代码如何同时执行500个操作
来源:stackoverflow
时间:2024-03-12 13:03:27 394浏览 收藏
目前golang学习网上已经有很多关于Golang的文章了,自己在初次阅读这些文章中,也见识到了很多学习思路;那么本文《解释下这段使用 Go 通道的代码如何同时执行500个操作》,也希望能帮助到大家,如果阅读完后真的对你学习Golang有帮助,欢迎动动手指,评论留言并分享~
我正在查找有关如何有效执行大量 http 请求的知识,我发现了这个答案:https://stackoverflow.com/a/23319730/749851,其中包含以下代码:
package main import ( "flag" "fmt" "log" "net/http" "runtime" "time" ) var ( reqs int max int ) func init() { flag.IntVar(&reqs, "reqs", 1000000, "Total requests") flag.IntVar(&max, "concurrent", 200, "Maximum concurrent requests") } type Response struct { *http.Response err error } // Dispatcher func dispatcher(reqChan chan *http.Request) { defer close(reqChan) for i := 0; i < reqs; i++ { req, err := http.NewRequest("GET", "http://localhost/", nil) if err != nil { log.Println(err) } reqChan <- req } } // Worker Pool func workerPool(reqChan chan *http.Request, respChan chan Response) { t := &http.Transport{} for i := 0; i < max; i++ { go worker(t, reqChan, respChan) } } // Worker func worker(t *http.Transport, reqChan chan *http.Request, respChan chan Response) { for req := range reqChan { resp, err := t.RoundTrip(req) r := Response{resp, err} respChan <- r } } // Consumer func consumer(respChan chan Response) (int64, int64) { var ( conns int64 size int64 ) for conns < int64(reqs) { select { case r, ok := <-respChan: if ok { if r.err != nil { log.Println(r.err) } else { size += r.ContentLength if err := r.Body.Close(); err != nil { log.Println(r.err) } } conns++ } } } return conns, size } func main() { flag.Parse() runtime.GOMAXPROCS(runtime.NumCPU()) reqChan := make(chan *http.Request) respChan := make(chan Response) start := time.Now() go dispatcher(reqChan) go workerPool(reqChan, respChan) conns, size := consumer(respChan) took := time.Since(start) ns := took.Nanoseconds() av := ns / conns average, err := time.ParseDuration(fmt.Sprintf("%d", av) + "ns") if err != nil { log.Println(err) } fmt.Printf("Connections:\t%d\nConcurrent:\t%d\nTotal size:\t%d bytes\nTotal time:\t%s\nAverage time:\t%s\n", conns, max, size, took, average) }
我来自节点,所以我不太理解这个“go”代码。
它的哪一部分将其限制为一次 500 个 http 操作?它是否以 500 块为一组进行操作,等待 500 块完成,然后开始新的 500 块,或者它总是在达到 499 块时再加 1 块,等等。
我发现“workerpool”函数的循环次数与最大并发请求数相同,调用“worker”500 次,但它最终如何执行接下来的 500 次甚至整个 100 万次?
解决方案
不是 500,而是 200,神奇的线条是:
for i := 0; i < max; i++ { go worker(t, reqChan, respChan) }
最大默认为200;并且可以用命令行开关覆盖。 这些“go 例程”中的每一个都类似于极其轻量级的线程,初始化自身然后等待通道输入。这就是神奇发生的地方 - 当请求进来时,它会导致在通道上发送。最多有 (200) 个 go 例程从该通道接收,并且该通道是无缓冲的,因此最多可以处理 200 个请求。第 201 个将导致发送方等待,直到其中一个工作人员完成并调用接收 (<-) 操作。
go 消息传递的微妙之处值得更好,并且稍微谷歌一下就会发现写得很好的文章、教程和 go 中并发的示例。
祝 go 好运;我认为这是一门美妙的语言。它优雅、富有表现力、简洁。你可能再也无法忍受 c++ 或 java...
文中关于的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《解释下这段使用 Go 通道的代码如何同时执行500个操作》文章吧,也可关注golang学习网公众号了解相关技术文章。
-
502 收藏
-
502 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
139 收藏
-
204 收藏
-
325 收藏
-
477 收藏
-
486 收藏
-
439 收藏
-
357 收藏
-
352 收藏
-
101 收藏
-
440 收藏
-
212 收藏
-
143 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 508次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习