Go 语言入门指南:基础语法和常用特性解析(二 Goroutines) | 青训营

65 阅读3分钟

Go语言的Goroutines简介

Go语言的并发模型以其轻量级的Goroutines为特色,为开发者提供了一种高效、安全且易于使用的方式来实现并发操作。这篇文章将深入介绍Goroutines的概念、创建、调度以及与传统线程的对比,帮助开发者全面理解这一核心特性。

Goroutines

Goroutines是Go语言的并发执行单元,每个Goroutine都是独立的执行线程,由Go运行时系统进行管理。相较于传统线程,Goroutines拥有更小的栈空间,因此可以创建数千甚至数百万个Goroutines,而不会引发内存资源问题。

创建Goroutines

创建一个Goroutine非常简单,只需在函数调用前加上关键字go即可。如:

go function()

这样就会在一个新的Goroutine中执行函数function,而主线程会继续执行后续代码。Goroutines的创建和销毁速度非常快,使得并发编程变得更加轻松。

Goroutines的调度

Go运行时系统负责Goroutines的调度和管理。它会将Goroutines分配给可用的逻辑核心,实现真正的并发执行。Goroutines之间的切换非常快速,这使得程序可以高效利用多核处理器,从而提高性能。

通信与同步

Goroutines之间的通信和同步是通过通道(Channels)实现的。通道是一种数据结构,用于在不同的Goroutines之间传递数据。通道的发送和接收操作会自动阻塞,直到数据准备好,从而实现了并发操作的安全性和同步。

Goroutines与传统线程的对比

与传统线程相比,Goroutines拥有许多优势:

  1. 轻量级: Goroutines的创建和销毁非常迅速,每个Goroutine只需几KB的内存。

  2. 并发性能: 大量的Goroutines可以在多核处理器上高效并发执行,提高程序性能。

  3. 通信简单: 通过通道进行通信和同步,避免了传统线程的共享内存竞争问题。

  4. 资源消耗小: Goroutines的资源消耗较小,可以创建大量并发任务而不引发资源耗尽。

实际应用示例

以下是一个示例:

package main
 
import (
    "runtime"
    "sync"
    "fmt"
)
 
func main() {
 
    // 分配一个逻辑处理器给调度器使用
    runtime.GOMAXPROCS(1)
 
    // wg用来等待程序完成,计数加2,表示要等待两个goroutine
    var wg sync.WaitGroup
    wg.Add(2)
    fmt.Println("Start Goroutines")
 
    // 声明一个匿名函数,并创建一个goroutine
    go func() {
        // 延时调用,在函数退出时调用done来通知main函数工作已经完成
        defer wg.Done()
        // 显示字母表三次
        for count := 0; count < 3; count ++ {
            for char := 'a'; char < 'a' + 26 ; char ++  {
                fmt.Printf("%c ", char)
            }
        }
    }()
    go func() {
        defer wg.Done()
        for count := 0; count < 3; count ++ {
            for char := 'A'; char < 'A' + 26 ; char ++  {
                //time.Sleep(time.Millisecond)
                fmt.Printf("%c ", char)
            }
        }
    }()
    fmt.Println("Wating To Finish")
    wg.Wait()
    fmt.Println("\nTerminating Program")
}

在这个示例当中,WaitGroup是一个计数信号量,它可以用来记录并维护运行的goroutinue。关键字defer会修改函数调用的时机,在正在执行的函数返回时调用defer声明的函数。

总结和感受

Goroutines是Go语言并发编程的核心特性,通过其轻量级、高效的执行模型,为开发者提供了一种更加简单、安全和高性能的并发编程方式。因此理解Goroutines的创建、调度、通信和同步机制是十分重要的。它可以帮助开发者充分发挥多核处理器的性能,编写出高效、可维护的并发程序。开发者通过掌握Goroutines,在开发工作中可以更好地应对现代应用中的并发挑战,提升代码的质量和性能。