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

相关推荐
LSTM979 分钟前
C# 实战:轻松提取 PDF 文件中的文字内容
后端
smchaopiao20 分钟前
Python中字典与列表合并的问题与解决方法
开发语言·python
PFinal社区_南丞34 分钟前
Skills与脚本:当智能遇上死板,一场编程界的"冰与火之歌"
后端
敲代码的瓦龙38 分钟前
Java?面向对象三大特性!!!
java·开发语言
树上有只程序猿38 分钟前
低代码何时能出个“秦始皇”一统天下?我是真学不动啦!
前端·后端·低代码
2501_9216494939 分钟前
期货 Tick 级数据与基金净值历史数据 API 接口详解
开发语言·后端·python·websocket·金融·区块链
架构师沉默40 分钟前
AI 写的代码,你敢上线吗?
java·后端·架构
野犬寒鸦43 分钟前
Redis复习记录day1
服务器·开发语言·数据库·redis·缓存
小菜鸡桃蛋狗1 小时前
C++——类和对象(下)
开发语言·c++