快上网专注成都网站设计 成都网站制作 成都网站建设
成都网站建设公司服务热线:028-86922220

网站建设知识

十年网站开发经验 + 多家企业客户 + 靠谱的建站团队

量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决

go语言线程是什么意思 go协程和线程

golang的线程模型——GMP模型

内核线程(Kernel-Level Thread ,KLT)

我们提供的服务有:做网站、成都做网站、微信公众号开发、网站优化、网站认证、卓资ssl等。为成百上千企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的卓资网站制作公司

轻量级进程(Light Weight Process,LWP):轻量级进程就是我们通常意义上所讲的线程,由于每个轻量级进程都由一个内核线程支持,因此只有先支持内核线程,才能有轻量级进程

用户线程与系统线程一一对应,用户线程执行如lo操作的系统调用时,来回切换操作开销相对比较大

多个用户线程对应一个内核线程,当内核线程对应的一个用户线程被阻塞挂起时候,其他用户线程也阻塞不能执行了。

多对多模型是可以充分利用多核CPU提升运行效能的

go线程模型包含三个概念:内核线程(M),goroutine(G),G的上下文环境(P);

GMP模型是goalng特有的。

P与M一般是一一对应的。P(上下文)管理着一组G(goroutine)挂载在M(内核线程)上运行,图中左边蓝色为正在执行状态的goroutine,右边为待执行状态的goroutiine队列。P的数量由环境变量GOMAXPROCS的值或程序运行runtime.GOMAXPROCS()进行设置。

当一个os线程在执行M1一个G1发生阻塞时,调度器让M1抛弃P,等待G1返回,然后另起一个M2接收P来执行剩下的goroutine队列(G2、G3...),这是golang调度器厉害的地方,可以保证有足够的线程来运行剩下所有的goroutine。

当G1结束后,M1会重新拿回P来完成,如果拿不到就丢到全局runqueue中,然后自己放到线程池或转入休眠状态。空闲的上下文P会周期性的检查全局runqueue上的goroutine,并且执行它。

另一种情况就是当有些P1太闲而其他P2很忙碌的时候,会从其他上下文P2拿一些G来执行。

详细可以翻看下方第一个参考链接,写得真好。

最后用大佬的总结来做最后的收尾————

Go语言运行时,通过核心元素G,M,P 和 自己的调度器,实现了自己的并发线程模型。调度器通过对G,M,P的调度实现了两级线程模型中操作系统内核之外的调度任务。整个调度过程中会在多种时机去触发最核心的步骤 “一整轮调度”,而一整轮调度中最关键的部分在“全力查找可运行G”,它保证了M的高效运行(换句话说就是充分使用了计算机的物理资源),一整轮调度中还会涉及到M的启用停止。最后别忘了,还有一个与Go程序生命周期相同的系统监测任务来进行一些辅助性的工作。

浅析Golang的线程模型与调度器

Golang CSP并发模型

Golang线程模型

golang多线程简单逻辑

实现指定个核心最大化使用,比如核心总数减一。

必要的库。

要使用的cpu数量,建议不全使用。

建立管道。

声明使用的cpu数。

建立互斥关系,本例中主要为了实现所有线程执行完后再执行后续程序。

创建cpu数减1个线程

后面每个任务结束时要done一个wg,这里根据具体情况加,是循环就在每个循环里加,保证后面能全部done即可

没有缓冲的、阻塞式的往管道传递字符串。

Wait是等所有线程都执行完,即增加的数字被全done掉。

关闭管道。

假设已有的函数是ReadLogs,在它的基础上加个Wg加函数名的新函数,我觉得这种方式不改变原有的,比较舒服。

大意是:循环从管道读取字符串,读不到了就跳出循环。

每个ReadLogs()之后加一个wg.Done(),相当于计数减一。

ReadLogs()就是要执行的任务,不再解释。

就是开指定个线程。

管道阻塞传值。

wg同步。

WgReadLogs循环接收。

go语言是单线程吗

是。go语言属于c语言软件中的编程语言,该编程语言是单线程的。c语言是一种通用程序设计语言类的程序软件。

Golang 线程和协程的区别

线程:

多线程是为了解决CPU利用率的问题,线程则是为了减少上下文切换时的开销,进程和线程在Linux中没有本质区别,最大的不同就是进程有自己独立的内存空间,而线程是共享内存空间。

在进程切换时需要转换内存地址空间,而线程切换没有这个动作,所以线程切换比进程切换代价要小得多。

协程:

想要简单,又要性能高,协程就可以达到我们的目的,它是用户视角的一种抽象,操作系统并没有这个概念,主要思想是在用户态实现调度算法,用少量线程完成大量任务的调度。

Goroutine是GO语言实现的协程,其特点是在语言层面就支持,使用起来十分方便,它的核心是MPG调度模型:M即内核线程;P即处理器,用来执行Goroutine,它维护了本地可运行队列;G即Goroutine,代码和数据结构;S及调度器,维护M和P的信息。

Go语言——goroutine并发模型

参考:

Goroutine并发调度模型深度解析手撸一个协程池

Golang 的 goroutine 是如何实现的?

Golang - 调度剖析【第二部分】

OS线程初始栈为2MB。Go语言中,每个goroutine采用动态扩容方式,初始2KB,按需增长,最大1G。此外GC会收缩栈空间。

BTW,增长扩容都是有代价的,需要copy数据到新的stack,所以初始2KB可能有些性能问题。

更多关于stack的内容,可以参见大佬的文章。 聊一聊goroutine stack

用户线程的调度以及生命周期管理都是用户层面,Go语言自己实现的,不借助OS系统调用,减少系统资源消耗。

Go语言采用两级线程模型,即用户线程与内核线程KSE(kernel scheduling entity)是M:N的。最终goroutine还是会交给OS线程执行,但是需要一个中介,提供上下文。这就是G-M-P模型

Go调度器有两个不同的运行队列:

go1.10\src\runtime\runtime2.go

Go调度器根据事件进行上下文切换。

调度的目的就是防止M堵塞,空闲,系统进程切换。

详见 Golang - 调度剖析【第二部分】

Linux可以通过epoll实现网络调用,统称网络轮询器N(Net Poller)。

文件IO操作

上面都是防止M堵塞,任务窃取是防止M空闲

每个M都有一个特殊的G,g0。用于执行调度,gc,栈管理等任务,所以g0的栈称为调度栈。g0的栈不会自动增长,不会被gc,来自os线程的栈。

go1.10\src\runtime\proc.go

G没办法自己运行,必须通过M运行

M通过通过调度,执行G

从M挂载P的runq中找到G,执行G


分享文章:go语言线程是什么意思 go协程和线程
文章源于:http://6mz.cn/article/docgcgg.html

其他资讯