这个其实不是错误,2个写法没有区别。-2015.11.22

认识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/

个人犯的一个golang routine错误的更多相关文章

  1. 开源一个golang小程序商城后台系统(moshopserver)

    开源一个golang小程序商城后台(moshopserver) golang和c/c++比起来是一门新的语言,一直想学,网上搜集了一些资料,有些人说很容易上手,确实是这样,和C/C++比起来,少了很多 ...

  2. 从0写一个Golang日志处理包

    WHY 日志概述 日志几乎是每个实际的软件项目从开发到最后实际运行过程中都必不可少的东西.它对于查看代码运行流程,记录发生的事情等方面都是很重要的. 一个好的日志系统应当能准确地记录需要记录的信息,同 ...

  3. 关于启动 SecureCRT 遇到一个致命的错误且必须关闭

    --------------------------SecureCRT---------------------------SecureCRT 遇到一个致命的错误且必须关闭. 一个崩溃转储文件已创建于 ...

  4. Windows下一个MySQL有些错误的解决方法

    1.无论是什么提示.我们有一个直接看错误日志.由于它描述了最具体描述错误日志. 于MySQL安装文件夹中找到 my.ini简介 看日志保存路径 2. 我的错误是[ERROR] Fatal error: ...

  5. 又是一个愚蠢的错误,皆因.xml而起

       论java中的.xml到底有多坑?! 感觉自己都快哭了,再一次被.xml给坑了一下,这次坑的太狠了,一下子导致自己浪费了昨天一下午,一晚上,今天一上午和半个下午呀,中间的过程真的是乏善可陈呀,各 ...

  6. “SecureCRT遇到一个致命的错误且必须关闭”处理办法

    打开SecureCRT时报错:SecureCRT遇到一个致命的错误且发须关闭.一个崩溃转储文件已创建于... 解决办法是,如下在cmd中输入regedit回车打开注册表编缉器 展开HKEY_LOCAL ...

  7. 推荐一个GOLANG入门很好的网址

    推荐一个GOLANG入门很好的网址,栗子很全 https://books.studygolang.com/gobyexample/

  8. 全局配置一个ajax的错误监控

    全局配置一个ajax的错误监控,比如$(document).ajaxError(function(evt, req, settings){    if(req && (req.stat ...

  9. golang error错误处理

    error定义 数据结构 go语言error是一普通的值,实现方式为简单一个接口. // The error built-in interface type is the conventional i ...

随机推荐

  1. vim 常用命令(一)特殊删除

    dd 可以删除光标当前行: ndd  n代表行数,3dd,删除从当前光标往下3行: di 删除在指定符号内的内容,如 空号,引号内: dt 删除当前光标到指定符号的内容

  2. spring配置文件引入properties文件:<context:property-placeholder>标签使用总结

    一.问题描述: 1.有些参数在某些阶段中是常量,比如: (1)在开发阶段我们连接数据库时的连接url.username.password.driverClass等 (2)分布式应用中client端访问 ...

  3. SSL编程(3).NET实现SSL服务端

      准备开发用数字证书 一般学习和开发调试场合,不会随便使用正式的SSL服务器证书的私钥.由于服务器验证对于SSL来说是必须的,SSL服务器端必须有拥有一个服务器 证书,即能够访问到证书的私钥.对于要 ...

  4. UVa 122 Trees on the level(链式二叉树的建立和层次遍历)

    题目链接: https://cn.vjudge.net/problem/UVA-122 /* 问题 给出每个节点的权值和路线,输出该二叉树的层次遍历序列. 解题思路 根据输入构建链式二叉树,再用广度优 ...

  5. MVC应用程序播放FLV视频,部分视图可多地方重复引用

    网页上播放Falsh之外,还有一种格式就是FLV的视频,也是最常见的.Insus.NET再想在MVC应用程序实现这功能. 实现这个功能,需要从网上下载一个叫vcastr22.swf.如果在网上找不到, ...

  6. 撩课-Web大前端每天5道面试题-Day36

    1.介绍一下你对浏览器内核的理解? 主要分成两部分:渲染引擎(layout engineer或Rendering Engine)和JS引擎. 渲染引擎:负责取得网页的内容(HTML.XML.图像等等) ...

  7. 微信公众号内唤起h5支付详解

    1.调用统一下单的接口URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder 2.调用统一下单必传参数: appid:需要进行支付功能的公众号的app ...

  8. 设计模式——适配器模式(type-c转3.5mm耳机口)

    本文首发于cdream的个人博客,点击获得更好的阅读体验! 欢迎转载,转载请注明出处. 本文简述适配器模式,考虑到java中没有多继承就只写了对象适配器模式,然后例子是怎么用转接口把3.5mm耳机插在 ...

  9. VirtualBox配置centos7静态ip(详解)

    VirtualBox安装centos7配置静态ip地址可以本机访问,可以联网. 在开始之前先说一下,不知道为什么,我在网上百度的大多数是不能用的,或者只能主机访问,或者只能联网. 我的配置文件为ifc ...

  10. Android-事件分发(ViewGroup)

    http://blog.csdn.net/guolin_blog/article/details/9153747 http://blog.csdn.net/lmj623565791/article/d ...