ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
> 协程是Go语言的关键特性,主要用于并发编程,协程是一种轻量级的线程,因为协程开销比较小,所以创建上万的协程也不是什么难事 [TOC] ## 创建并运行协程 > 通过go关键词创建一个协程 ``` go dotest() ``` > 例子 > go携程特性:当主携程退出后,子携程随之退出 ``` package main import ( "fmt" "strconv" "time" ) // 定义一个函数,循环打印5次字符串 func say(name string) { for i := 0; i < 5; i++ { // 当前协程休眠1秒 time.Sleep(1000 * time.Millisecond) fmt.Println(name + strconv.FormatInt(int64(i), 10)) } } // 程序启动的时候,首先创建一个主协程,运行main函数 func main() { // 创建一个协程,运行say函数,传入参数"wk" go say("wk") // 在主协程中运行say函数,传入参数"jiaojiao" go say("jiaojiao") // 以下代码,设置无线循环,可组织主携程退出 /*for { ; }*/ } ``` > 以上例子,wk和jiaojiao交叉输出,但是有可能say("jiaojiao")函数先执行完成,主程就会退出,导致say("wk")函数的携程没有执行完毕就终止了。 > 解决这种问题,就需要用到`channel通信`,如下 ~~~ package main import "fmt" func doubleNum(num int, c chan int) { c <- num * 2 } func main() { // 定义一个无缓冲区的channel,用来接收协程计算结果 channel := make(chan int) // 创建第1协程 go doubleNum(3, channel) // 创建第2个协程 go doubleNum(2, channel) // 使用channel读取,会进行阻塞,直到有数据后,才会往下执行 x := <-channel y := <-channel // 打印计算结果,主程退出 fmt.Println(x, y, x+y) } ~~~ ## 协程通信 > 协程之间通信主要有两种方式 > * [共享全局变量](https://www.tizi365.com/archives/457.html):因为协程本身是在同一个进程中运行,所以可以共享变量,但是为了解决并发问题,保证数据原子性,需要加锁处理。 > * channel:管道通信,避免复杂的加锁操作(下篇将进行介绍)