协程(goroutine)的使用

package main

import (
   "fmt"
   "time"
)

func test() {
   for i := 0; i < 5; i++ {
      fmt.Printf("协程(具名函数) i = %+v \n", i)
      time.Sleep(time.Second) // 休眠1秒
   }
}

func main() {
   // 开启协程(具名函数)
   go test()

   // 开启协程(匿名函数)
   go func() {
      for i := 0; i < 5; i++ {
         fmt.Printf("协程(匿名函数) i = %+v \n", i)
         time.Sleep(time.Second) // 休眠1秒
      }
   }()

   // 主线程的for循环
   for i := 0; i < 5; i++ {
      fmt.Printf("主线程 i = %+v \n", i)
      time.Sleep(time.Second) // 休眠1秒
   }

   // ========== 输出过程·开始 ========== //
   // 主线程 i = 0
   // 协程(匿名函数) i = 0
   // 协程(具名函数) i = 0
   // 协程(具名函数) i = 1
   // 协程(匿名函数) i = 1
   // 主线程 i = 1
   // 协程(具名函数) i = 2
   // 协程(匿名函数) i = 2
   // 主线程 i = 2
   // 主线程 i = 3
   // 协程(匿名函数) i = 3
   // 协程(具名函数) i = 3
   // 协程(具名函数) i = 4
   // 协程(匿名函数) i = 4
   // 主线程 i = 4
   // ========== 输出过程·结束 ========== //
}

// ========== 总结 ========== //
// 1、Go开启协程非常简单,使用go关键字,在其后面调用具名函数或匿名函数即可。
// 2、协程是依附主线程的,即只要主线程退出了,不管协程有没有开始或执行到哪里,协程都会退出。以上面的代码为例,如果把两个协程
//    的for循环放到主线程之后,那么两个协程就都不会执行了,因为主线程执行完for循环就会退出。
//    对于协程嵌套的情况亦是如此,父协程和子协程都是依附主线程的,在主线程没退出的前提下,父协程执行完并不会中断子协程的执行。
// 3、协程的调度永远是不可预测的,即在设置了多个协程的情况下,开发者永远不知道哪个协程会先执行,即便是代码里出现了诸如
//    runtime.GOMAXPROCS(1)、runtime.Gosched()等语句,这些函数的作用仅仅只是让协程的切换变得频繁,并不会让协程的调度变得可预测。

Copyright © 2025 码农人生. All Rights Reserved