分享
  1. 首页
  2. 文章

个人犯的一个golang routine错误

nonsuch · · 6092 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

认识golang也不少时间了,也做过几个项目。最近发现之前用golang写的一个服务,内存涨得比较快,一直没找出来原因来。今天把疑惑发到群里,经过golang学习班的童鞋的指点,发现我一个常用的错误。

在不少golang入门的文章上,用并发的例子一般是这样写的;

package main
import (
 "fmt"
 "time"
)
func main() {
 messages := make(chan int)
 go func() {
 time.Sleep(time.Second * 3)
 messages <- 1
 }()
 go func() {
 time.Sleep(time.Second * 2)
 messages <- 2
 }() 
 go func() {
 time.Sleep(time.Second * 1)
 messages <- 3
 }()
 go func() {
 for i := range messages {
 fmt.Println(i)
 }
 }()
 time.Sleep(time.Second * 5)
}

我之前的项目,也一直是这样写。今天和群里的讨论了下,才发觉,这个写法其实是比较丑陋的。

其实可以通过这个去实现。

package main
import (
 "fmt"
 "io/ioutil"
 "log"
 "net/http"
 "sync"
)
func main() {
 urls := []string{
 "http://www.reddit.com/r/aww.json",
 "http://www.reddit.com/r/funny.json",
 "http://www.reddit.com/r/programming.json",
 }
 jsonResponses := make(chan string)
 var wg sync.WaitGroup
 wg.Add(len(urls))
 for _, url := range urls {
 go func(url string) {
 defer wg.Done()
 res, err := http.Get(url)
 if err != nil {
 log.Fatal(err)
 } else {
 defer res.Body.Close()
 body, err := ioutil.ReadAll(res.Body)
 if err != nil {
 log.Fatal(err)
 } else {
 jsonResponses <- string(body)
 }
 }
 }(url)
 }
 go func() {
 for response := range jsonResponses {
 fmt.Println(response)
 }
 }()
 wg.Wait()
}

这个更简单,而且也更方便使用。性能方面,应该比chan要好点。

我之前的一个案例是,client发一个http request过来, 服务器收到请求,然后同时开N个go routine去处理,然后每个处理完成后,通过chan 进行传递给主线程,主线程判断chan的是否接收完成所有的请求,然后再响应。

就是用的第一种方法。

今天根据群里面体的建议,重构了下。使用list来处理每个用户请求。

比如,有个全局Map变量: map[int]list, 每个请求创建一个巍峨唯一的随机数或者sessionId, 然后每个go rouine处理完后,根据sessionid去查找对应的list, 插入数据。

可以利用list来实现异步队列的机制,避免锁。

所以特地在这记录下来,当然各位新人的参考。

附上国外的一篇文章: http://nathanleclaire.com/blog/2014/02/15/how-to-wait-for-all-goroutines-to-finish-executing-before-continuing/


有疑问加站长微信联系(非本文作者)

本文来自:博客园

感谢作者:nonsuch

查看原文:个人犯的一个golang routine错误

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
6092 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏