NipGeihou's blog NipGeihou's blog
  • Java

    • 开发规范
    • 进阶笔记
    • 微服务
    • 快速开始
    • 设计模式
  • 其他

    • Golang
    • Python
    • Drat
  • Redis
  • MongoDB
  • 数据结构与算法
  • 计算机网络
  • 应用

    • Grafana
    • Prometheus
  • 容器与编排

    • KubeSphere
    • Kubernetes
    • Docker Compose
    • Docker
  • 组网

    • TailScale
    • WireGuard
  • 密码生成器
  • 英文单词生成器
🍳烹饪
🧑‍💻关于
  • 分类
  • 标签
  • 归档

NipGeihou

我见青山多妩媚,料青山见我应如是
  • Java

    • 开发规范
    • 进阶笔记
    • 微服务
    • 快速开始
    • 设计模式
  • 其他

    • Golang
    • Python
    • Drat
  • Redis
  • MongoDB
  • 数据结构与算法
  • 计算机网络
  • 应用

    • Grafana
    • Prometheus
  • 容器与编排

    • KubeSphere
    • Kubernetes
    • Docker Compose
    • Docker
  • 组网

    • TailScale
    • WireGuard
  • 密码生成器
  • 英文单词生成器
🍳烹饪
🧑‍💻关于
  • 分类
  • 标签
  • 归档
  • Java视角看Go

    • 前言
    • 环境安装
    • 介绍
    • 基本语法
    • 集合
    • 面向对象
    • 反射
    • 协程
      • 什么是协程
      • 协程的创建
      • 协程的退出
      • 协程的通信
        • 无缓冲的channel
        • 有缓冲的channel
    • 常见库
  • other

  • 笔记

  • 代码片段

  • Golang
  • Java视角看Go
NipGeihou
2023-01-05
目录

协程

# 什么是协程

协程是一种比线程更加轻量级的存在,它是由用户态的线程调度器来调度的,而不是由操作系统内核来调度。

在应用层面可以理解为就是 Java 中的线程,但是协程的实现方式和 Java 中的线程有很大的不同。

相较于Java的线程解决了什么问题

  • 线程的创建和销毁需要操作系统内核的参与,而协程的创建和销毁只需要用户态的线程调度器的参与,因此协程的创建和销毁比线程更加轻量级。

# 协程的创建

协程的创建需要使用 go 关键字,例如:

package main

import (
    "fmt"
    "time"
)


func main() {
    // 匿名函数创建协程
    go func() {
        fmt.Println("hello")
    }()

    // 函数创建协程
    go hello()

    time.Sleep(time.Second)
}

func hello() {
    fmt.Println("hello")
}

# 协程的退出

协程的退出有两种方式:

  • 协程中的函数执行完毕,协程自动退出
  • 协程中的函数使用 return 关键字退出

# 协程的通信

协程之间的通信可以使用 channel 来实现, channel 是一种特殊的类型,它可以让协程之间进行通信。

# 无缓冲的 channel

package main

import "fmt"

func main() {
    // 定义一个channel
    c := make(chan int)

    go func() {
        defer fmt.Println("子协程结束")

        fmt.Println("子协程开始")

        c <- 666
    }()
    
    num := <- c // 从channel中取出数据

    fmt.Println("num = ", num)
    fmt.Println("main协程结束")

}

image-20230106153750905

  • 在第 1 步,两个 goroutine 都到达通道,但哪个都没有开始执行发送或者接收。
  • 在第 2 步,左侧的 goroutine 将它的手伸进了通道,这模拟了向通道发送数据的行为。这时,这个 goroutine 会在通道中被锁住,直到交换完成。
  • 在第 3 步,右侧的 goroutine 将它的手放入通道,这模拟了从通道里接收数据。这个 goroutine 一样也会在通道中被锁住,直到交换完成。
  • 在第 4 步和第 5 步,进行交换,并最终,在第 6 步,两个 goroutine 都将它们的手从通道里拿出来,这模拟了被锁住的 goroutine 得到释放。两个 goroutine 现在都可以去做其他事情了。

# 有缓冲的 channel

image-20230106154335191

上次更新: 2024/03/11, 22:37:05
反射
常见库

← 反射 常见库→

最近更新
01
iSCSI服务搭建
05-10
02
磁盘管理与文件系统
05-02
03
网络测试 - iperf3
05-02
更多文章>
Theme by Vdoing | Copyright © 2018-2025 NipGeihou | 友情链接
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式