Go基础语法知识整理

时间:2025-04-22 08:19:16
  • Go 从 语言层面 就支持并发。同时实现了 自动垃圾回收 机制
  • 进程/线程
    • 进程是程序在操作系统中的一次 执行过程系统 进行 资源分配调度 的一个 独立单位
    • 线程是进程的一个 执行实体 ,是 CPU 调度分派基本单位 ,它是比进程 更小 的能 独立运行基本单位
    • 一个进程可以 创建和撤销 多个线程,同一个进程中的多个线程之间可以 并发 执行。
  • 并发/并行
    • 多线程 程序在 单核心 的 cpu 上运行,称为 并发
    • 多线程 程序在 多核心 的 cpu 上运行,称为 并行
    • 并发与并行并不相同,并发主要由 切换时间片 来实现(准) “同时”运行 ,并行则是直接 利用多核 实现 多线程的运行 ,Go程序可以 设置使用核心数 ,以发挥多核计算机的能力。
  • 协程/线程
    • 协程: 独立栈空间共享堆空间 ,调度由 用户 自己 控制 ,本质上有点类似于 用户级线程 ,这些用户级线程的调度也是自己实现的。
    • 线程: 一个线程 上可以跑 多个协程协程是轻量级的线程
  • Goroutine 一般将其翻译为Go协程,也就是说Go语言在 语言层面 就实现了 协程的支持
  • Go程序会 智能 地将 goroutine 中的任务合理地 分配 给每个CPU
  • 程序员只需要定义很多个任务,让系统去把这些任务分配到CPU上实现并发执行

  • Go语言编程中不需要去自己写进程、线程、协程,当需要让某个任务并发执行的时候,只需要把这个任务包装成一个函数,开启一个goroutine去执行这个函数就可以了
  • 主协程 退出了,子协程还会执行吗? ,只要main函数没有结束,协程就会继续执行。
  • 函数与函数间需要交换数据才能体现并发执行函数的意义;
  • 共享内存在不同的goroutine中容易发生 竞态 问题;
  • 为保证数据交换的 正确性 而使用 互斥量 对内存进行 加锁 会造成 性能 问题;
  • Go语言的并发模型是 CSP (Communicating Sequential Processes),提倡 通过通信共享内存 而不是通过共享内存而实现通信
  • channel就是并发的goroutine之间的 连接
  • 通道像一个传送带或者队列,总是遵循 先入先出 (First In First Out)的规则
  • 声明通道后需要使用 make函数初始化 之后才能使用
  • 关闭后的通道有以下特点:
    • 对一个关闭的通道再发送值就会导致panic。
    • 对一个关闭的通道进行接收 会一直获取值 直到通道为空。
    • 嗯?

    • 对一个关闭的并且没有值的通道执行接收操作会得到对应类型的 零值
    • 关闭一个已经关闭的通道会导致panic。
  • 使用无缓冲通道进行通信将导致发送和接收的goroutine 同步化 。因此, 无缓冲通道也被称为同步通道
  • 如何判断一个通道是否被关闭?
    • i, ok := <-ch1 // 通道关闭后再取值ok=false
    • for i := range ch2 { // 通道关闭后会退出for range循环
  • 在函数传参及任何赋值操作中将双向通道转换为单向通道是可以的,但反过来是不可以的;
  • select可以同时监听一个或多个channel,直到其中一个channel ready;
  • Go语言中使用sync包的Mutex类型来实现互斥锁;使用sync包中的RWMutex类型来实现读写锁;
  • 代码中的 加锁操作 因为 涉及内核态的上下文切换 会比较耗时、代价比较高;
  • 针对 基本数据类型 我们还可以使用 原子操作 来保证并发安全,原子操作是Go语言提供的方法它在 用户态 就可以完成