【Go语言学习系列28】并发编程(一):goroutine基础

📚 原创系列: “Go语言学习系列”

🔄 转载说明: 本文最初发布于"Gopher部落"微信公众号,经原作者授权转载。

🔗 关注原创: 欢迎扫描文末二维码,关注"Gopher部落"微信公众号获取第一手Go技术文章。

📑 Go语言学习系列导航

本文是【Go语言学习系列】的第28篇,当前位于第三阶段(进阶篇)

🚀 第三阶段:进阶篇
  1. 并发编程(一):goroutine基础👈 当前位置
  2. 并发编程(二):channel基础
  3. 并发编程(三):select语句
  4. 并发编程(四):sync包
  5. 并发编程(五):并发模式
  6. 并发编程(六):原子操作与内存模型
  7. 数据库编程(一):SQL接口
  8. 数据库编程(二):ORM技术
  9. Web开发(一):路由与中间件
  10. Web开发(二):模板与静态资源
  11. Web开发(三):API开发
  12. Web开发(四):认证与授权
  13. Web开发(五):WebSocket
  14. 微服务(一):基础概念
  15. 微服务(二):gRPC入门
  16. 日志与监控
  17. 第三阶段项目实战:微服务聊天应用

📚 查看完整Go语言学习系列导航

📖 文章导读

在本文中,您将了解:

  • goroutine的概念及其与传统线程的核心区别
  • Go运行时如何管理和调度goroutine
  • 如何正确创建和使用goroutine
  • CSP并发模型的基本思想与应用
  • 避免goroutine泄漏和竞态条件的最佳实践
  • 在实际项目中应用goroutine的常见模式

无论您是并发编程新手还是有经验的开发者,本文都将帮助您掌握Go语言最具特色的并发特性,为编写高效可靠的并发程序奠定基础。

Go并发编程模型


并发编程(一):goroutine基础

并发编程是Go语言最具特色的功能之一,它使得我们能够轻松地编写高效的并发程序。Go语言通过goroutine和channel两大核心机制,为开发者提供了简单而强大的并发编程模型。本文将深入探讨goroutine的基础知识,帮助你掌握Go语言并发编程的基本技能。

一、goroutine概念与特性

goroutine是Go语言并发设计的核心,它是一种轻量级的用户态线程,由Go运行时(runtime)管理。

1.1 goroutine与线程的区别

goroutine与传统线程相比有诸多优势:

  1. 极低的创建和切换成本

    • goroutine的初始栈大小仅有2KB(Go 1.18后为2KB,此前是8KB)
    • 而线程的栈通常是MB级别
  2. 动态栈大小

    • goroutine的栈大小可以根据需要动态增长和收缩
    • 最大可达1GB(64位系统)
  3. 高效的调度模型

    • Go运行时实现了M:N的调度模型
    • 多个goroutine(N)可以在少量系统线程(M)上运行
    • 避免了上下文切换的高成本
  4. 与线程的数量对比

    • 系统可以轻松支持数十万甚至数百万的goroutine同时运行
    • 创建同等数量的线程会耗尽系统资源

1.2 goroutine的工作原理

Go运行时负责goroutine的创建、调度和销毁:

┌─────────────────────┐
│     Go 应用程序       │
│  ┌───────┬───────┐  │
│  │ goroutine    │  │
│  │ goroutine    │  │
│  │ ...          │  │
│  └───────┴───────┘  │
└──────────┬──────────┘
           │
┌──────────▼──────────┐
│     Go 运行时        │
│  ┌───────┬───────┐  │
│  │ 调度器 │ GC    │  │
│  └───────┴───────┘  │
└──────────┬──────────┘
           │
┌──────────▼──────────┐
│      操作系统        │
│  ┌───────┬───────┐  │
│  │ 线程   │ 内存   │  │
│  └───────┴───────┘  │
└─────────────────────┘
  • GMP模型:Go调度器基于GMP模型工作
    • G: goroutine,用户级线程
    • M: machine,操作系统线程
    • P: processor,调度上下文,负责连接M和G

二、启动与调度

在Go中启动goroutine非常简单,只需使用go关键字即可。

2.1 创建goroutine

package main

import (
    "fmt"
    "time"
)

func sayHello() {
   
   
    fmt.Println("Hello from goroutine!")
}

func main() {
   
   
    // 启动一个goroutine
    go sayHello()
    
    // 防止主goroutine退出太快
    time.Sleep(100 * time.Millisecond)
    fmt.Println("Main function finished")
}

在这个例子中:

  1. go sayHello() 启动了一个新的goroutine执行sayHello函数
  2. 主函数不会等待goroutine完成,需要通过time.Sleep让主goroutine等待

2.2 传递参数

启动goroutine时可以传递参数:

func printValue(val int) {
   
   
    fmt.Printf("Value: %d\n", val)
}

func main() {
   
   
    for i := 0; i < 5; i++ {
   
   
        // 通过函数参数传值
        go printValue(i)
    }
    time.Sleep(100 * time.Millis
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gopher部落

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值