Golang 并发性Goroutines

Golang 并发性Goroutines

Go语言提供了一个特殊的功能,称为Goroutines。一个Goroutine是一个独立执行的函数或方法,它与程序中存在的任何其他Goroutine同时进行。换句话说,Go语言中每个同时执行的活动都被称为Goroutines。你可以把Goroutine看作是一个轻量级的线程。与线程相比,创建Goroutines的成本非常小。每个程序至少包含一个Goroutine,这个Goroutine被 称为主Goroutine。 所有的Goroutine都在主Goroutine下工作,如果主Goroutine终止了,那么程序中的所有Goroutine也就终止了。Goroutine总是在后台工作。

如何创建一个Goroutine

你可以通过使用go关键字作为函数或方法调用的前缀来创建你自己的Goroutine,如下面的语法所示。

语法

func name(){
// statements
}

// using go keyword as the 
// prefix of your function call
go name()

例子

// Go program to illustrate
// the concept of Goroutine
package main
  
import "fmt"
  
func display(str string) {
    for w := 0; w < 6; w++ {
        fmt.Println(str)
    }
}
  
func main() {
  
    // Calling Goroutine
    go display("Welcome")
  
    // Calling normal function
    display("GeeksforGeeks")
}

输出

GeeksforGeeks
GeeksforGeeks
GeeksforGeeks
GeeksforGeeks
GeeksforGeeks
GeeksforGeeks

在上面的例子中,我们简单地创建了一个display()函数,然后以两种不同的方式调用这个函数,第一种是Goroutine,即go display(“Welcome”),另一种是普通函数,即display(“GeeksforGeeks”) 。但是有一个问题,它只显示普通函数的结果,而不显示Goroutine的结果,因为当一个新的Goroutine执行时,Goroutine调用立即返回。控件不会像普通函数那样等待Goroutine完成其执行,它们总是在Goroutine调用后前进到下一行,并忽略Goroutine返回的值。因此,为了正确地执行Goroutine,我们在程序中做了一些修改,如下面的代码所示。

修改后的例子

// Go program to illustrate the concept of Goroutine
package main
  
import (
    "fmt"
    "time"
)
  
func display(str string) {
    for w := 0; w < 6; w++ {
        time.Sleep(1 * time.Second)
        fmt.Println(str)
    }
}
  
func main() {
  
    // Calling Goroutine
    go display("Welcome")
  
    // Calling normal function
    display("GeeksforGeeks")
}

输出

Welcome
GeeksforGeeks
GeeksforGeeks
Welcome
Welcome
GeeksforGeeks
GeeksforGeeks
Welcome
Welcome
GeeksforGeeks
GeeksforGeeks

我们在程序中添加了Sleep()方法,使主Goroutine休眠1秒,在1秒之间,新的Goroutine执行,在屏幕上显示 “欢迎”,然后在1秒后终止,主Goroutine重新计划并执行其操作。这个过程一直持续到z<6的值,然后主Goroutine就终止了。在这里,Goroutine和普通函数都是同时工作的。

Goroutine的优点

  • Goroutine比线程更便宜。
  • Goroutine存储在堆栈中,堆栈的大小可以根据程序的要求而增长和缩小。但在线程中,堆栈的大小是固定的。
  • Goroutine可以使用通道进行通信,这些通道是专门为防止使用Goroutine访问共享内存时出现竞赛条件而设计的。
  • 假设一个程序有一个线程,而这个线程有许多Goroutine与之相关。如果任何一个Goroutine由于资源需求而阻塞了线程,那么所有剩下的Goroutine将被分配给一个新创建的操作系统线程。所有这些细节都是对程序员隐藏的。

匿名Goroutine

在Go语言中,你也可以为一个匿名函数启动Goroutine,或者换句话说,你可以通过使用go关键字作为该函数的前缀来创建一个匿名Goroutine,如下图所示。

语法

// Anonymous function call
go func (parameter_list){
// statement
}(arguments)

例子

// Go program to illustrate how
// to create an anonymous Goroutine
package main
  
import (
    "fmt"
    "time"
)
  
// Main function
func main() {
  
    fmt.Println("Welcome!! to Main function")
  
    // Creating Anonymous Goroutine
    go func() {
  
        fmt.Println("Welcome!! to GeeksforGeeks")
    }()
  
    time.Sleep(1 * time.Second)
    fmt.Println("GoodBye!! to Main function")
}

输出

Welcome!! to Main function
Welcome!! to GeeksforGeeks
GoodBye!! to Main function

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程