go语言并发编程1-Gouroutine

参考文档:www.topgoer.com

使用方法

直接包装成函数,go关键字触发即可

注意事项

1 main方法结束后,main方法内启动的子协程会立即结束,无论是否执行完毕;

启动多个groutine

使用sync包的WaitGroup来控制,等待每一个协程执行完毕:

go 复制代码
package main

import (
	"fmt"
	"sync"
	"time"
)

func printHello(wg *sync.WaitGroup) {
	time.Sleep(3 * time.Second)
	defer wg.Done()
	fmt.Println("__hello__")
}

func main() {
	var wg sync.WaitGroup
	wg.Add(3)
	go printHello(&wg)
	go printHello(&wg)
	go printHello(&wg)
	wg.Wait()
}

要知道协程执行顺序,以上代码可以修改为:

go 复制代码
package main

import (
	"fmt"
	"sync"
	"time"
)

var wg sync.WaitGroup

func printHello(i int) {
	defer wg.Done()
	time.Sleep(3 * time.Second)
	fmt.Printf("__hello:%d__\n", i)
}

func main() {
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go printHello(i)
	}
	wg.Wait()
}

根据打印结果来看,执行是无序的。

goroutine与线程

goroutine生命周期开始时的栈默认只有2kb,可以按需增大或缩小,最大可到1GB,一次性创造10万个goroutine也是可以的。

goroutine调度

GPM是Go语言运行时(runtime)层面的实现,是go语言自己实现的一套调度系统。区别于操作系统调度OS线程;

G:goroutine

P:processor处理器,管理着一组goroutine队列,P里面会存储当前goroutine运行的上下文环境(函数指针,堆栈地址及地址边界),P会对自己管理的goroutine队列做一些调度

M:machine,是Go运行时(runtime)对操作系统内核线程的虚拟, M与内核线程一般是一一映射的关系, 一个groutine最终是要放到M上执行的。

P与M一般也是一一对应的。他们关系是: P管理着一组G挂载在M上运行。当一个G长久阻塞在一个M上时,runtime会新建一个M,阻塞G所在的P会把其他的G 挂载在新建的M上。当旧的G阻塞完成或者认为其已经死掉时 回收旧的M

相关推荐
前端 贾公子3 小时前
v-if 与 v-for 的优先级对比
开发语言·前端·javascript
行百里er4 小时前
2026:一名码农的“不靠谱”年度规划
后端·程序员·架构
嗯嗯=4 小时前
python学习篇
开发语言·python·学习
不会c嘎嘎6 小时前
QT中的常用控件 (二)
开发语言·qt
计算机程序设计小李同学7 小时前
基于SpringBoot的个性化穿搭推荐及交流平台
java·spring boot·后端
是一个Bug7 小时前
50道核心JVM面试题
java·开发语言·面试
用户47949283569157 小时前
同事一个比喻,让我搞懂了Docker和k8s的核心概念
前端·后端
她和夏天一样热7 小时前
【观后感】Java线程池实现原理及其在美团业务中的实践
java·开发语言·jvm
lkbhua莱克瓦247 小时前
进阶-索引3-性能分析
开发语言·数据库·笔记·mysql·索引·性能分析
郑州光合科技余经理7 小时前
技术架构:上门服务APP海外版源码部署
java·大数据·开发语言·前端·架构·uni-app·php