博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Go语言并发组件
阅读量:2176 次
发布时间:2019-05-01

本文共 2158 字,大约阅读时间需要 7 分钟。

Go中的并发组件

1、Goroutine

Goroutine: go语言程序中最基本的组织单位之一,每个Go程序中至少会有一个main goroutine,在进程开始时自动创建并启动。是一个并发函数,在程序中使用go关键字进行触发

gorountine如何工作?
A、goroutine与Go语言在运行时是深度集成的
B、goroutine没有定义自己的暂停方法或再运行点
C、Go语言再运行时会观察goroutine的运行时行为,再它们阻塞时自动挂起,不阻塞时恢复,使得goroutione在阻塞时成为可抢占的
D、协程和goroutione是隐式并发结构,但并发不是二者的属性

它们是OS线程或绿色线程吗?

Goroutine不是,是更高级别的抽象协程

绿色线程:相对于操作系统线程,操作系统线程是指程序中会真正的映射到操作系统的线程,绿色线程是指程序中不会映射到操作系统中有语言映射平台自身来调度(由语言运行时管理的线程)协程:非抢占式的简单并发子goroutine(函数, 闭包或方法), 不能被中断,协程由多个点允许暂停或重新进入

Go语言的主机托管机制:M:N调度器

M个绿色线程映射到N个OS线程,goroutine数量如果大于绿色线程时,这时调度程序会处理分布在可用线程上的goroutine,保证正常运行
Go语言的并发模型fork-join模型:
fork-join并发模型
fork:指在程序的任意一点,可以将执行的子分支与其父节点同时运行
join:将来某个时间,这些并发的执行分支将会合并在一起

Goroutine与GC:

用于计算创建一个goroutine消耗的内存

memConsumed := func ()uint64{		runtime.GC()		var s runtime.MemStats		runtime.ReadMemStats(&s)		return s.Sys	}	var c <-chan interface{}	var wg sync.WaitGroup	noop := func(){ wg.Done(); <-c}	const numGoroutines = 1e4	wg.Add(numGoroutines)	before := memConsumed()	for i := numGoroutines; i > 0; i--{		go noop()	}	wg.Wait()	after := memConsumed()	fmt.Printf("%.3fkb", float64(after - before)/numGoroutines/1000)

理论上8GB内存的计算机在不交换空间的情况下可以启动百万量级的goroutine,可能会影响性能的是上下文,因为OS线程的开销是相当大的,相比之下软件的上下文切换就会廉价

OS线程切换上下文:os线程必须保存如:寄存器,查找表和内存映射之类的东西,以便在有限的时间内成功地切换回当前线程
对比OS线程和goroutine之间切换上下文时的相对性能对比:

Linux基准测试taskset -c 0 perf bench sched pipe -T结果:# Running 'sched/pipe' benchmark:# Executed 1000000 pipe operations between two threads     Total time: 2.276 [sec]       2.276609 usecs/op         439249 ops/sec
go中的测试func BenchmarkContestSwitch(b *testing.B){	var wg sync.WaitGroup	begin := make(chan struct{})	c := make(chan struct{})	var token struct{}	sender := func(){		defer wg.Done()		<- begin		for i := 0; i < b.N; i++{			c <- token		}	}	receiver := func(){		defer wg.Done()		<-begin		for i := 0; i < b.N; i++{			<-c		}	}	wg.Add(2)	go sender()	go receiver()	b.StartTimer()	close(begin)	wg.Wait()}结果go test -bench=. -cpu=1  goroutine_test.gogoos: linuxgoarch: amd64BenchmarkContestSwitch 	10000000	       144 ns/opPASSok  	command-line-arguments	1.597s

高效机制背后的秘密

1、goroutine既不是os线程。也不是应用层线程。
2、golang的M:N调度器。
3、golang的轻:一个新创建的goroutine赋予了几千字节,不运行,go会自动缩减内存。
4、goroutine的fork-join模型。

转载地址:http://gdfkb.baihongyu.com/

你可能感兴趣的文章
【虫师】【selenium】参数化
查看>>
【Python练习】文件引用用户名密码登录系统
查看>>
学习网站汇总
查看>>
【Python】用Python打开csv和xml文件
查看>>
【Loadrunner】性能测试报告实战
查看>>
【自动化测试】自动化测试需要了解的的一些事情。
查看>>
【selenium】selenium ide的安装过程
查看>>
【手机自动化测试】monkey测试
查看>>
【英语】软件开发常用英语词汇
查看>>
Fiddler 抓包工具总结
查看>>
【雅思】雅思需要购买和准备的学习资料
查看>>
【雅思】雅思写作作业(1)
查看>>
【雅思】【大作文】【审题作业】关于同不同意的审题作业(重点)
查看>>
【Loadrunner】通过loadrunner录制时候有事件但是白页无法出来登录页怎么办?
查看>>
【English】【托业】【四六级】写译高频词汇
查看>>
【托业】【新东方全真模拟】01~02-----P5~6
查看>>
【托业】【新东方全真模拟】03~04-----P5~6
查看>>
【托业】【新东方托业全真模拟】TEST05~06-----P5~6
查看>>
【托业】【新东方托业全真模拟】TEST09~10-----P5~6
查看>>
【托业】【新东方托业全真模拟】TEST07~08-----P5~6
查看>>