个人犯的一个golang routine错误
这个其实不是错误,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错误的更多相关文章
- 开源一个golang小程序商城后台系统(moshopserver)
开源一个golang小程序商城后台(moshopserver) golang和c/c++比起来是一门新的语言,一直想学,网上搜集了一些资料,有些人说很容易上手,确实是这样,和C/C++比起来,少了很多 ...
- 从0写一个Golang日志处理包
WHY 日志概述 日志几乎是每个实际的软件项目从开发到最后实际运行过程中都必不可少的东西.它对于查看代码运行流程,记录发生的事情等方面都是很重要的. 一个好的日志系统应当能准确地记录需要记录的信息,同 ...
- 关于启动 SecureCRT 遇到一个致命的错误且必须关闭
--------------------------SecureCRT---------------------------SecureCRT 遇到一个致命的错误且必须关闭. 一个崩溃转储文件已创建于 ...
- Windows下一个MySQL有些错误的解决方法
1.无论是什么提示.我们有一个直接看错误日志.由于它描述了最具体描述错误日志. 于MySQL安装文件夹中找到 my.ini简介 看日志保存路径 2. 我的错误是[ERROR] Fatal error: ...
- 又是一个愚蠢的错误,皆因.xml而起
论java中的.xml到底有多坑?! 感觉自己都快哭了,再一次被.xml给坑了一下,这次坑的太狠了,一下子导致自己浪费了昨天一下午,一晚上,今天一上午和半个下午呀,中间的过程真的是乏善可陈呀,各 ...
- “SecureCRT遇到一个致命的错误且必须关闭”处理办法
打开SecureCRT时报错:SecureCRT遇到一个致命的错误且发须关闭.一个崩溃转储文件已创建于... 解决办法是,如下在cmd中输入regedit回车打开注册表编缉器 展开HKEY_LOCAL ...
- 推荐一个GOLANG入门很好的网址
推荐一个GOLANG入门很好的网址,栗子很全 https://books.studygolang.com/gobyexample/
- 全局配置一个ajax的错误监控
全局配置一个ajax的错误监控,比如$(document).ajaxError(function(evt, req, settings){ if(req && (req.stat ...
- golang error错误处理
error定义 数据结构 go语言error是一普通的值,实现方式为简单一个接口. // The error built-in interface type is the conventional i ...
随机推荐
- 20-hadoop-pagerank的计算
转: http://www.cnblogs.com/rubinorth/p/5799848.html 参考尚学堂视频 1, 概念( 来自百度百科) PageRank是Google专有的算法,用于衡量特 ...
- Solidity之mapping类型
映射是一种引用类型,存储键值对.它的定义是:mapping(key => value),概念上与java中的map,python中的字典类型类似,但在使用上有比较多的限制. 一.mapping定 ...
- spring web应用
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...
- VMware12 克隆虚拟机并且重新分配ip、mac
记录如何快速拷贝一台虚拟机,并且重新分配IP.mac等方便自己做实验: 环境:VMWare12 .Redhat6.8 Step1.克隆虚拟机 虚拟机处于未打开状态,右击管理—>克隆 弹出克隆界 ...
- Spring Aop AfterReturning接收返回值
包结构: Spring.xml UserDao.java 测试类Main方法 LogAspect.java 测试结果: @AfterReturning标签属性分析: value值: 可以写Aop的表达 ...
- 在Bootstrap框架中,form-control的效果
在Bootstrap框架中,通过定制了一个类名`form-control`,也就是说,如果这几个元素使用了类名“form-control”,将会实现一些设计上的定制效果. 1.宽度变成了100% 2. ...
- wamp3.1.0 X64下载链接
Wamp3.1.0 X64下载 链接:https://pan.baidu.com/s/1UUU62whfUtiH2_nGFKdQAg 密码:h92l
- 【转】CSRF基本概念
本文转自:http://www.cnblogs.com/hyddd/ 一.CSRF是什么? CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one ...
- [转]SQL Server 2008 如何配置报表管理器
本文转自:https://docs.microsoft.com/zh-cn/previous-versions/sql/sql-server-2008/cc281384%28v%3dsql.100%2 ...
- 彻底理解voliate
1.voliate简介 在上一篇文章中我们深入理解了java关键字synchronized,我们知道在java中还有一大神器就是关键volatile,可以说是和synchronized各领风骚,其中奥 ...