文档章节

Go里面sync.WaitGroup指针引用问题

Kanonpy
 Kanonpy
发布于 2018/09/18 18:50
字数 460
阅读 34
收藏 0

WaitGroup:主要包括Add,Done,Wait三个方法,Add表示添加一个goroutine,Done等于Add(-1),表示一个goroutine结束,wait表示主线程一直等到所有的goroutine执行完成,并且阻塞主线程的执行,直到所有的goroutine执行完成.

但在使用的时候发现进程一直阻塞,代码如下:

func Exec(url string, wg sync.WaitGroup) error{
	statusCode, body, err := fasthttp.Get(nil, url)
	if err != nil{
		log.Fatalf("err,%s", err)
		return err
	}
	if statusCode != fasthttp.StatusOK {
		log.Fatalf("Unexpected status code: %d")
		return err
	}
	ParseBody(body)
	wg.Done()
	return nil
}

func main(){
	var URL string
	URL = "http://192.168.2.112:61208/"
	num := 100
	var wg sync.WaitGroup
	wg.Add(num)
	startTime := time.Now()
	for i:=0; i<num; i++{
		go Exec(URL, wg)
	}
	wg.Wait()
	endTime := time.Now()
	spendTime := endTime.Sub(startTime)
	log.Println(spendTime)
}

将sync.WaitGroup放在main中做done就可以正常运行:

func main(){
	var URL string
	URL = "http://192.168.2.112:61208/"
	num := 100
	var wg sync.WaitGroup
	wg.Add(num)
	startTime := time.Now()
	for i:=0; i<num; i++{
		go func(){
			statusCode, body, err := fasthttp.Get(nil, url)
			if err != nil{
				log.Fatalf("err,%s", err)
			}
			if statusCode != fasthttp.StatusOK {
				log.Fatalf("Unexpected status code: %d")
			}
			ParseBody(body)
			wg.Done() 
		}
	}
	wg.Wait()
	endTime := time.Now()
	spendTime := endTime.Sub(startTime)
	log.Println(spendTime)
}

一直阻塞应该是死锁了,也就是wg.Done()没起作用,原来是wg 给拷贝传递到了 goroutine 中,导致只有 Add 操作,其实 Done操作是在 wg 的副本执行导致的~~ 将wg 的传入类型改为 *sync.WaitGrou,这样就能引用到正确的WaitGroup了

func Exec(url string, wg *sync.WaitGroup) error{
	statusCode, body, err := fasthttp.Get(nil, url)
	if err != nil{
		log.Fatalf("err,%s", err)
		return err
	}
	if statusCode != fasthttp.StatusOK {
		log.Fatalf("Unexpected status code: %d")
		return err
	}
	ParseBody(body)
	wg.Done()
	return nil
}

func main(){
	var URL string
	URL = "http://192.168.2.112:61208/"
	num := 100
	var wg sync.WaitGroup
	wg.Add(num)
	startTime := time.Now()
	for i:=0; i<num; i++{
		go Exec(URL, &wg)
	}
	wg.Wait()
	endTime := time.Now()
	spendTime := endTime.Sub(startTime)
	log.Println(spendTime)
}

© 著作权归作者所有

Kanonpy
粉丝 16
博文 42
码字总数 45373
作品 0
广州
程序员
私信 提问
golang使用闭包时的共享变量问题

在并发的使用golang闭包的时候有一个共享变量问题要注意一下,看一段代码 输出结果 ???什么情况,为什么不是0 ~ 4 的乱序组合? 因为主协程和子协程是有执行顺序的,也就是使用主协程在一...

anoty
2017/02/20
600
8
如何优雅的控制goroutine的数量

1,为什么要控制goroutine的数量? goroutine固然好,但是数量太多了,往往会带来很多麻烦,比如耗尽系统资源导致程序崩溃,或者CPU使用率过高导致系统忙不过来。比如: 2,用什么方法控制gor...

borey
2016/05/27
6.5K
11
没有深度的问题,但求有深度的回答:关于C语言中的引用。

C语言中的指针和引用,相信用过一段时间这个语言的朋友在使用上应该都不陌生吧。说说引用。引用用起来不难,可以使用的几个场景,大概也都算熟悉。但是,有几点,始终是我不明了的,恳求大家...

穿着马甲的鸟
2011/07/23
1K
25
同步之sync.Pool临时对象池

同步之sync.Pool临时对象池 当多个goroutine都需要创建同一个对象的时候,如果goroutine过多,可能导致对象的创建数目剧增。 而对象又是占用内存的,进而导致的就是内存回收的GC压力徒增。造...

秋风醉了
2016/08/05
573
0
OC底层知识(十二) : 内存管理

一、抛出一个问题:使用、 有什么注意点?1.1-1.6的demo // 保证调用频率和屏幕的刷帧频率一致 60FPSself.link = [CADisplayLink displayLinkWithTarget:self selector:@selector(linkTest)]...

IIronMan
2018/11/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

计算机实现原理专题--二进制减法器(二)

在计算机实现原理专题--二进制减法器(一)中说明了基本原理,现准备说明如何来实现。 首先第一步255-b运算相当于对b进行按位取反,因此可将8个非门组成如下图的形式: 由于每次做减法时,我...

FAT_mt
今天
5
0
好程序员大数据学习路线分享函数+map映射+元祖

好程序员大数据学习路线分享函数+map映射+元祖,大数据各个平台上的语言实现 hadoop 由java实现,2003年至今,三大块:数据处理,数据存储,数据计算 存储: hbase --> 数据成表 处理: hive --> 数...

好程序员官方
今天
7
0
tabel 中含有复选框的列 数据理解

1、el-ui中实现某一列为复选框 实现多选非常简单: 手动添加一个el-table-column,设type属性为selction即可; 2、@selection-change事件:选项发生勾选状态变化时触发该事件 <el-table @sel...

everthing
今天
6
0
【技术分享】TestFlight测试的流程文档

上架基本需求资料 1、苹果开发者账号(如还没账号先申请-苹果开发者账号申请教程) 2、开发好的APP 通过本篇教程,可以学习到ios证书申请和打包ipa上传到appstoreconnect.apple.com进行TestF...

qtb999
今天
10
0
再见 Spring Boot 1.X,Spring Boot 2.X 走向舞台中心

2019年8月6日,Spring 官方在其博客宣布,Spring Boot 1.x 停止维护,Spring Boot 1.x 生命周期正式结束。 其实早在2018年7月30号,Spring 官方就已经在博客进行过预告,Spring Boot 1.X 将维...

Java技术剑
今天
18
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部