go基本用法

发布于:2025-07-06 ⋅ 阅读:(16) ⋅ 点赞:(0)

1. mod

go mod init github.com/yourusername/myproject

2.导包

函数大写:对外开放public

匿名导包_

起别名

3.数据类型

​Go 中所有参数传递本质上都是值传递​​,map 和 slice、channel 等类型之所以表现出引用传递的特性,是因为它们内部包含指向底层数据的指针

struct:实现类,封装、继承

interface(父类指针):多态,interface{}万能类型,value, ok = arg.(string)

4.Go调度器核心设计策略详解

1. 线程复用机制(Thread Reuse)

Go调度器通过三级结构实现线程复用:

  • ​M(Machine)​​:操作系统线程实体
  • ​P(Processor)​​:逻辑处理器,含本地运行队列
  • ​G(Goroutine)​​:轻量级协程

工作流程:

  1. 空闲M会尝试绑定一个P(默认P数量=GOMAXPROCS)
  2. P从其本地队列(LRQ)取出G交给M执行
  3. 当G阻塞时,M会解绑P并进入休眠,P转而寻找其他可用M
  4. G执行结束后返回队列,M继续获取新任务

复用优势:

  • 避免频繁创建/销毁OS线程(系统调用开销大)
  • 通过P的中间层解耦M与G的关系
  • 本地队列减少全局锁竞争

2. 并行执行策略(Parallelism)

Go通过三层并行设计充分利用多核:

  • ​GOMAXPROCS控制P数量​​:通常设为CPU核心数
  • ​每个P独立调度​​:拥有本地运行队列,无锁访问
  • ​工作窃取(Work Stealing)​​:空闲P会从其他P或全局队列偷G

并行特性:

  • 真正的物理并行(非并发)
  • P之间无通信开销
  • 自动负载均衡

3. 协作式抢占(Cooperative Preemption)

抢占触发点:

  1. ​显式让出点​​:

    • 通道操作(发送/接收)
    • 系统调用
    • 函数调用(编译器插入检查指令)
  2. ​时间片耗尽​​(Go 1.14+):

    • 异步抢占信号(基于信号机制)
    • 默认时间片10ms

G1运行中 -> 到达抢占点 -> 保存上下文 -> 放回队列 -> 调度器选择G2 -> 恢复G2上下文

演进历史:

  • Go 1.2:只在函数调用时检查抢占
  • Go 1.14:引入基于信号的全面抢占

4. 全局Goroutine管理

两级队列设计:

+------------------+       +------------------+
|  全局运行队列    |<----->|    P的本地队列    |
| (GRQ)           |       | (LRQ)           |
| [G1][G2][G3]... |       | [G4][G5]...     |
+------------------+       +------------------+

负载均衡策略:

  1. ​新建Goroutine​​:

    • 优先放入当前P的LRQ
    • LRQ满时放入GRQ
  2. ​调度选择顺序​

  • 本地队列(LRQ)
  • 全局队列(GRQ)
  • 网络轮询器(network poller)
  • 从其他P窃取

设计哲学:

  1. ​层次化​​:M-P-G三级结构各司其职
  2. ​本地化​​:优先使用本地资源减少竞争
  3. ​弹性​​:动态调整资源分配
  4. ​高效​​:最小化调度开销(纳秒级切换)

网站公告

今日签到

点亮在社区的每一天
去签到