go 协程管理及传参处理

 基础语法  2022-10-18  admin  1859  2509

Go语言中的goroutine虽然相对于系统线程来说比较轻量级(初始栈大小仅2KB),(并且支持动态扩容),而正常采用java,c++等语言启用的线程一般都是内核态的占用的内存资源一般在4m左右,而假设我们的服务器CPU内存为4G,那么很明显才用的内核态线程的并发总数量也就是1024个,相反查看一下Go语言的协程则可以达到4*1024*1024/2=200w.这么一看就明白了为什么Go语言天生支持高并发

但是在高并发量下的goroutine频繁创建和销毁对于性能损耗以及GC来说压力也不小。充分将goroutine复用,减少goroutine的创建/销毁的性能损耗,这便是grpoolgoroutine进行池化封装的目的。例如,针对于100W个执行任务,使用goroutine的话需要不停创建并销毁100Wgoroutine,而使用grpool也许底层只需要几万个goroutine便能充分复用地执行完成所有任务。



异步执行时并不会保证按照函数注册时的顺序执行

对于异步线程/协程来讲,函数进行异步执行注册时,该函数并未真正开始执行(注册时只在goroutine的栈中保存了变量i的内存地址),

而一旦开始执行时函数才会去读取变量i的值,而这个时候变量i的值已经自增到了10。

清楚原因之后,改进方案也很简单了,就是在注册异步执行函数的时候,把当时变量i的值也一并传递获取;

或者把当前变量i的值赋值给一个不会改变的临时变量,在函数中使用该临时变量而不是直接使用变量i。

// 在注册异步执行函数的时候,把当时变量i的值也一并传递获取;
wg := sync.WaitGroup{}
for i := 0; i < 10; i++ {
	wg.Add(1)
	go func(v int) {
		fmt.Println(v)
		wg.Done()
	}(i)
}
wg.Wait()
//0
//9
//7
//8
//5
//2
//1
//3
//6
//4
//把当前变量i的值赋值给一个不会改变的临时变量,在函数中使用该临时变量而不是直接使用变量i
//采用临时变量的形式来传递当前变量i的值
wg3 := sync.WaitGroup{}
for i := 0; i < 10; i++ {
	wg3.Add(1)
	a := i // 定义局部临时变量
	go func() {
		fmt.Println(a)
		wg3.Done()
	}()
}
wg3.Wait()
//9
//4
//0
//1
//2
//3
//6
//5
//7
//8

错误方式

// 相对于协程,i相当于全局变量
wg2 := sync.WaitGroup{}
for i := 0; i < 10; i++ {
	wg2.Add(1)
	go func() {
		fmt.Println(i)
		wg2.Done()
	}()
}
wg2.Wait()
//10
//10
//10
//10
//10
//10
//10
//10
//10
//10
//全局变量不可行
wg4 := sync.WaitGroup{}
var a int // 定义全局变量
for i := 0; i < 10; i++ {
	wg4.Add(1)
	a = i //
	go func() {
		fmt.Println(a)
		wg4.Done()
	}()
}
wg4.Wait()
//9
//9
//9
//9
//9
//9
//9
//9
//9
//9


如果文章对您有帮助,点击下方的广告,支持一下作者吧!

转载必须注明出处:

go 协程管理及传参处理 —— code.cent123.com

相关推荐


go 在Windows系统中交叉编译临时环境变量设置

go 编译临时环境变量设置并 交叉编译命令$env:GOOS=&quot;linux&quot;;$env:GOARCH=&quot;amd64&quot;;gobuild-ofilenametest.go$env:GOOS=&quot;linux&quot;;$env:GOARCH=&quot;amd64&quot;;`gobuild-ofilenametest.go`这两种方式 都是在Powe

phpstorm 设置 外部命令

C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.20.11781.0_x64__8wekyb3d8bbwe\wt.exe-d $ContentRoot$$ProjectFileDir$

点名工具,抽奖软件

点名工具,抽奖软件

酷炫的倒计时客户端

QQ: 425100867捐赠开发者: