何小豆儿在此 发表于 2023-9-24 06:16:33

Go协程揭秘:轻量、并发与性能的完美结合

Go协程为并发编程提供了强大的工具,结合轻量级、高效的特点,为开发者带来了独特的编程体验。本文深入探讨了Go协程的基本原理、同步机制、高级用法及其性能与最佳实践,旨在为读者提供全面、深入的理解和应用指导。
关注公众号【TechLeadCloud】,分享互联网架构、云服务技术的全维度知识。作者拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的资深架构师,项目管理专业人士,上亿营收AI产品研发负责人。
https://img2023.cnblogs.com/other/488581/202309/488581-20230919162325521-2042516450.jpg
1. Go协程简介

Go协程(goroutine)是Go语言中的并发执行单元,它比传统的线程轻量得多,并且是Go语言并发模型中的核心组成部分。在Go中,你可以同时运行成千上万的goroutine,而不用担心常规操作系统线程带来的开销。
什么是Go协程?

Go协程是与其他函数或方法并行运行的函数或方法。你可以认为它类似于轻量级的线程。其主要优势在于它的启动和停止开销非常小,相比于传统的线程来说,可以更有效地实现并发。
package main

import (
    "fmt"
    "time"
)

func sayHello() {
    for i := 0; i < 5; i++ {
      time.Sleep(100 * time.Millisecond)
      fmt.Println("Hello!")
    }
}

func main() {
    go sayHello() // 启动一个Go协程
    for i := 0; i < 5; i++ {
      time.Sleep(150 * time.Millisecond)
      fmt.Println("Hi!")
    }
}输出:
Hi!
Hello!
Hi!
Hello!
Hello!
Hi!
Hello!
Hi!
Hello!处理过程:
在上面的代码中,我们定义了一个sayHello函数,它在一个循环中打印“Hello!”五次。在main函数中,我们使用go关键字启动了sayHello作为一个goroutine。此后,我们又在main中打印“Hi!”五次。因为sayHello是一个goroutine,所以它会与main中的循环并行执行。因此,输出中“Hello!”和“Hi!”的打印顺序可能会变化。
Go协程与线程的比较


[*]启动开销:Go协程的启动开销远小于线程。因此,你可以轻松启动成千上万个goroutine。
[*]内存占用:每个Go协程的堆栈大小开始时很小(通常在几KB),并且可以根据需要增长和缩小,而线程通常需要固定的、较大的堆栈内存(通常为1MB或更多)。
[*]调度:Go协程是由Go运行时系统而不是操作系统调度的。这意味着Go协程之间的上下文切换开销更小。
[*]安全性:Go协程为开发者提供了简化的并发模型,配合通道(channels)等同步机制,减少了并发程序中常见的错误。
示例代码:
package mainimport (    "fmt"    "time")func worker(id int, ch chan int) {    for {      fmt.Printf("Worker %d received data: %d\n", id,
页: [1]
查看完整版本: Go协程揭秘:轻量、并发与性能的完美结合