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

相关推荐
为何创造硅基生物7 小时前
C语言 结构体内存对齐规则(通俗易懂版)
c语言·开发语言
吃好睡好便好7 小时前
在Matlab中绘制横直方图
开发语言·学习·算法·matlab
星寂樱易李7 小时前
iperf3 + Python-- 网络带宽、网速、网络稳定性
开发语言·网络·python
仰泳之鹅8 小时前
【C语言】自定义数据类型2——联合体与枚举
c语言·开发语言·算法
之歆8 小时前
DAY_12JavaScript DOM 完全指南(二):实战与性能篇
开发语言·前端·javascript·ecmascript
姚不倒8 小时前
Go语言进阶:接口、错误处理与并发编程(goroutine/channel/context)
云原生·golang
candyTong8 小时前
Claude Code 的 Edit 工具是怎么工作的
javascript·后端·架构
cen__y9 小时前
Linux12(Git01)
linux·运维·服务器·c语言·开发语言·git
AI人工智能+电脑小能手9 小时前
【大白话说Java面试题 第65题】【JVM篇】第25题:谈谈对 OOM 的认识
java·开发语言·jvm
GetcharZp9 小时前
GitHub 2.4 万 Star!D2 正在重新定义程序员画图方式
后端