Golang

关注公众号 jb51net

关闭
首页 > 脚本专栏 > Golang > goland goroutine用法

Golang 并发编程入门Goroutine 简介与基础用法小结

作者:Linke-

Goroutine 是 Golang 中的一种轻量级线程,用于实现并发操作,与传统线程相比,Goroutine 的优势在于它具有更低的资源消耗和更高的效率,本文介绍Golang 并发编程入门Goroutine 简介与基础用法小结,感兴趣的朋友一起看看吧

一、什么是 Goroutine?

Goroutine 是 Golang 中的一种轻量级线程,用于实现并发操作。与传统线程相比,Goroutine 的优势在于它具有更低的资源消耗和更高的效率。每个 Goroutine 在运行时被 Go 的调度器(Scheduler)管理,并且它们共享内存空间。这使得在单个系统线程上运行成千上万个 Goroutine 成为可能。

1、Goroutine 的特点:

二、如何启动 Goroutine

要启动 Goroutine,我们只需要在函数调用前加上 go 关键字。此操作会将该函数在单独的 Goroutine 中异步执行,主程序不会等待它完成。

语法:

go 函数名(参数)

示例 1:基本的 Goroutine 用法

package main
import (
    "fmt"
    "time"
)
func printMessage() {
    fmt.Println("Goroutine is running!")
}
func main() {
    go printMessage() // 启动 Goroutine
    time.Sleep(1 * time.Second) // 暂停主线程,确保 Goroutine 执行完
    fmt.Println("Main function is done.")
}

输出:

Goroutine is running!  
Main function is done.

解释:

三、主 Goroutine 与子 Goroutine 的关系

关键点:如果主 Goroutine 结束,所有未完成的子 Goroutine 也会被强制终止。

示例 2:主线程结束导致子 Goroutine 终止

package main
import (
    "fmt"
    "time"
)
func main() {
    go func() {
        time.Sleep(2 * time.Second)
        fmt.Println("This message may never appear.")
    }()
    fmt.Println("Main function is done.")
    // 主 Goroutine 立即结束,子 Goroutine 没有机会完成
}

输出:

Main function is done.

解释:

主 Goroutine 结束时,所有未完成的子 Goroutine 会立即停止,因此不会看到子 Goroutine 的输出。

四、Goroutine 的参数传递

在 Golang 中,Goroutine 支持传递参数,但需要注意是按值传递,而不是按引用。

示例 3:Goroutine 传递参数

package main
import (
    "fmt"
)
func printNumber(num int) {
    fmt.Println("Number:", num)
}
func main() {
    for i := 1; i <= 3; i++ {
        go printNumber(i) // 启动 Goroutine 传递参数
    }
    fmt.Scanln() // 等待用户输入,防止程序提前结束
}

输出(可能):

Number: 1  
Number: 2  
Number: 3

五、匿名函数中的变量捕获问题

Goroutine 常与匿名函数一起使用,但要小心变量捕获问题。在循环中启动 Goroutine 时,匿名函数可能捕获的不是当前迭代变量的值,而是循环结束后的变量。

示例 4:错误的变量捕获

package main
import (
    "fmt"
    "time"
)
func main() {
    for i := 1; i <= 3; i++ {
        go func() {
            fmt.Println(i) // 捕获的可能是循环结束后的 i
        }()
    }
    time.Sleep(1 * time.Second)
}

输出:

4  
4  
4

修改后的代码:将变量作为参数传递

go func(n int) {
    fmt.Println(n)
}(i)

六、使用 WaitGroup 等待 Goroutine 完成

time.Sleep 不是等待 Goroutine 完成的最佳方式。Go 提供了 sync.WaitGroup 来管理多个 Goroutine 的同步。

示例 5:使用 WaitGroup

package main
import (
    "fmt"
    "sync"
)
func printMessage(msg string, wg *sync.WaitGroup) {
    defer wg.Done() // Goroutine 完成时调用 Done()
    fmt.Println(msg)
}
func main() {
    var wg sync.WaitGroup
    wg.Add(3) // 等待 3 个 Goroutine
    go printMessage("Hello", &wg)
    go printMessage("from", &wg)
    go printMessage("Goroutine!", &wg)
    wg.Wait() // 等待所有 Goroutine 完成
    fmt.Println("All Goroutines are done.")
}

输出:

Hello  
from  
Goroutine!  
All Goroutines are done.

解释:

七、Goroutine 的典型应用场景

八、注意事项与最佳实践

九、小结

Goroutine 是 Golang 的强大并发工具,其高效、易用的特点让它成为开发者实现并发程序的首选。在这篇博客中,我们介绍了 Goroutine 的基础用法、参数传递和同步机制,并演示了常见的应用场景和注意事项。

到此这篇关于Golang 并发编程入门:Goroutine 简介与基础用法的文章就介绍到这了,更多相关goland goroutine用法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

阅读全文