Golang的Goroutines是什么?
#初学者 #编程 #go #bestofdev

Goroutines是Golang最独特,最常用的功能之一。 goroutines用于人员并发任务。 Goroutine只是一个轻巧的执行线程,也是与程序的其余部分同时执行的函数。与线程相比,创建Goroutine的成本很小。

在我们深入研究goroutines之前,首先要了解并发的含义。

并发和并行性

  • 并发是在两个或多个任务可以在重叠时间段开始,运行和完成的时候。这并不一定意味着他们都会在同一瞬间运行。并发是程序或系统的语义属性。并发是在重叠时间段内进行多个任务的时候。

  • 并行性是关于与多个计算资源(如多核处理器)同时在硬件上同时运行的相同任务的多个任务或子任务。并行性是实施属性。从字面上看,并行性是在运行时同时进行任务的物理执行,并且需要具有多个计算资源的硬件。它位于硬件层。

例如 - 如果您同时听音乐和阅读,那么这是并行的,因为您同时执行了两个任务。如果您正在听音乐,并且暂时暂停了音乐并开始阅读,那么您再次开始音乐并暂停阅读,这是并发。在这里,这两个任务是一起完成的,但没有同时完成。

什么是goroutines?

Goroutine是由GO运行时管理的轻量级线程。我们,使用Goroutines创建并发程序。并发程序能够同时运行多个进程。在节省时间的同时,为我们提供了同时处理信息的能力。 Goroutines是线程上轻巧的抽象,因为它们的创造和破坏与线程相比非常便宜,并且它们安排在OS线程上。要创建您只需要使用go Word启动文件,以下是一个示例

package main

import (  
    "fmt"
)

func hello() {  
    fmt.Println("Hello world goroutine")
}

func main() {  
    go hello()  // a go routine
    fmt.Println("main function")
}

go hello()启动了新的goroutine。现在,hello()函数将与main()函数同时运行。主函数以自己的goroutine运行,称为主goroutine。

要了解其工作,我们必须牢记一些事情。创建新的GO例程时,它将在父go例程中运行,该例程是执行代码的文件。如果文件内部的代码或父线程完成执行,则它也将终止子例程。因此,只有主要功能被打印,并且hello()例程与下一行中的父终止。主要的Goroutine应该运行,以供任何其他Goroutine运行。如果主要的goroutine终止,则该程序将被终止,并且没有其他Goroutine运行。那是秘密酱。

想想自己如何修复我们需要一些延迟,以便完成hello()例程执行,然后我们跳到下一行。为此,我们需要什么?一个简单的延迟!

package main

import (  
    "fmt"
    "time"
)

func hello() {  
    fmt.Println("Hello world goroutine")
}
func main() {  
    go hello()
    time.Sleep(1 * time.Second)  // here is the delay 
    fmt.Println("main function")
}

这将等待1秒钟,在那段时间,GO例程可以执行自身。现在,呼叫go hello()有足够的时间在主要Goroutine终止之前执行。该程序首先打印出Hello World Goroutine,1秒钟后,我们开始从下一行阅读。以相同的方式,我们可以根据需要创建多个GO例程。

是什么让它们与线程不同?

  • 通道:Goroutines具有一种简单的通信媒介,称为通道。由于第一通道的存在,Goroutine可以与其他延迟较低的Goroutines通信。线程没有简单的通信媒介。由于缺乏简单的通信媒介,线程间的通信发生在高潜伏期中。
  • 设置和拆卸成本:线程具有明显的设置和拆卸成本,因为它必须从操作系统中请求资源并完成后将其退还。当Go运行时创建和破坏Goroutines(它管理计划,垃圾收集和Goroutines的运行时环境),这些操作非常便宜。

  • 开关成本:这种差异主要是因为goroutines和螺纹的调度差异。线程是预先计划的(如果一个进程的运行超过调度程序时间片,它将在同一CPU上抢占过程和计划执行另一个可运行的过程),计划需要保存/还原所有寄存器

    < /li>

Image description

如何执行GO例程?

有三个实体用于解释Goroutine计划。

  • 处理器(P)

  • osthread(m)

  • goroutines(g)

go在一种名为M:N调度程序(M:N调度程序)的调度程序上使用,该调度程序指出,可以通过n个OS线程数将m数量的goroutines数量分布。相比之下,OS线程比Goroutines具有更多的开销。因此,GO使用有限数量的线程运行最大数量的Goroutines。

Image description

GO Scheduler在一个或多个处理器上运行的多个Worker OS线程上分发可运行的goroutines。每个P都有当地的goroutine队列。还有一个全球goroutine队列,其中包含可运行的goroutines。每个M应分配给P。PS如果被阻止或在系统调用中,则可能没有MS。

在任何时候,最多有gomaxprocs的p数,只有一个m可以运行。按时可以由调度程序创建更多的ms。在每一轮计划中,调度程序都可以找到可运行的G并执行它。一旦找到可运行的G,它将执行直到被阻止。

如果您做到这一点,请不要忘记放弃并发表评论!

参考
https://riteeksrivastava.medium.com/a-complete-journey-with-goroutines-8472630c7f5c

https://riteeksrivastava.medium.com/a-complete-journey-with-goroutines-8472630c7f5c

https://riteeksrivastava.medium.com/a-complete-journey-with-goroutines-8472630c7f5c

谢谢!