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

相关推荐
zm-v-159304339861 分钟前
解锁遥感数据密码:DeepSeek、Python 与 OpenCV 的协同之力
开发语言·python·opencv
周Echo周13 分钟前
20、map和set、unordered_map、un_ordered_set的复现
c语言·开发语言·数据结构·c++·算法·leetcode·list
明天更新18 分钟前
Java处理压缩文件的两种方式!!!!
java·开发语言·7-zip
老胖闲聊24 分钟前
C# 注册表操作类
开发语言·c#
勘察加熊人26 分钟前
Python+Streamlit实现登录页
开发语言·python
撸猫79127 分钟前
HttpSession 的运行原理
前端·后端·cookie·httpsession
理智的煎蛋31 分钟前
keepalived+lvs
java·开发语言·集成测试·可用性测试
嘵奇1 小时前
Spring Boot中HTTP连接池的配置与优化实践
spring boot·后端·http
Bl_a_ck1 小时前
【React】Craco 简介
开发语言·前端·react.js·typescript·前端框架
子燕若水1 小时前
Flask 调试的时候进入main函数两次
后端·python·flask