Go是一种并发语言,Go中使用Goroutine和channel处理并发
Goroutines是与其他函数or方法同时运行的函数or方法
Goroutines可以被认为是轻量级线程。与线程相比,创建Goroutine的成本很小。因此,Go应用程序通常会同时运行数千个Goroutine
Goroutines相对于线程的优势
- 与线程相比,Goroutines 非常便宜。它们的堆栈大小只有几 kb,堆栈可以根据应用程序的需要增长和缩小,而在线程的情况下,堆栈大小必须指定并固定。
- ==Goroutine 被多路复用到更少数量的 OS 线程。==一个包含数千个 Goroutine 的程序中可能只有一个线程。如果该线程中的任何 Goroutine 阻塞等待用户输入,则创建另一个 OS 线程并将剩余的 Goroutine 移动到新的 OS 线程。所有这些都由运行时处理,我们作为程序员从这些复杂的细节中抽象出来,并获得了一个干净的 API 来处理并发性。
- ==Goroutines 使用通道进行通信。==通道通过设计防止在使用 Goroutine 访问共享内存时发生竞争条件。通道可以被认为是 Goroutine 进行通信的管道。我们将在下一个教程中详细讨论频道。
如何启动一个Goroutine?
使用关键字为函数or方法调用添加前缀go,您将有一个新的Goroutine并发运行
package main
import "fmt"
func hello(){
fmt.Println("Hello world Goroutine!!!")
}
func main(){
go hello()//启动一个新的Goroutine
fmt.Println("main function")
}
现在该hello()函数将与该main()函数同时运行。main 函数在它自己的 Goroutine 中运行,它被称为main Goroutine。
我想现在你应该能够理解为什么我们的 Goroutine 没有运行了。在第11行调用go hello()后。主程立即返回到下一行代码,无需等待 hello goroutine 完成并打印main function。然后主 Goroutine 终止,因为没有其他代码可以执行,因此 hello Goroutine 没有机会运行。
goroutine的两个主要属性
- 当一个新的Goroutine启动时,goroutine调用立即返回。与函数不同,主程不等待Goroutine完成执行。在Goroutine调用之后,主程立即返回到下一行代码,并且Goroutine的任何返回值都将被忽略
- 主Goroutine应该正在运行以供任何其他Goroutines运行。如果主Goroutine终止,则程序终止,并且不会运行其他Goroutine。
解决问题