枫枫知道个人博客
首页
新闻
心情
关于
文章搜索
网站导航
项目相关
官方文档
首页
新闻
心情
关于
文章搜索
网站导航
项目相关
官方文档
登录
注册
go 协程
Goroutine是Go运行时管理的轻量级线程 主线程结束时
搜索
[[ slide_text ]]
[[ item.content ]]
1
1
go 协程
发布时间:
2022-12-04
作者:
枫枫
来源:
枫枫知道个人博客
Go
Goroutine是Go运行时管理的轻量级线程 主线程结束时,协程会被中断,需要有效的阻塞机制 # 协程的使用 ```Go package main import ( "fmt" "time" ) // SendCode 发送验证码 func SendCode() { fmt.Println("发送验证码开始") time.Sleep(3 * time.Second) fmt.Println("发送验证码完成!") } func main() { // 实现用户注册功能 fmt.Println("用户注册校验完成") // 发送验证码 //SendCode() // 会阻塞主线程 go SendCode() // 会阻塞主线程 fmt.Println("验证码已发送,请注意查收...") } ``` 问题: 1. 主线程结束,协程也会结束 2. 协程安全 3. 如何获取协程函数的返回值,如何在协程中传递数据? # WaitGroup 前面我们通过让主程序延时的方式,可以成功让协程函数顺利结束 但是,延时多久没人能够知道 所以,睡眠这种方式肯定不靠谱 go 自带一个WaitGroup可以解决这个问题, 代码如下 ```Go package main import ( "sync" ) var wg sync.WaitGroup func say(s string) { for i := 0; i < 5; i++ { println(s) } wg.Done() } func main() { wg.Add(2) go say("Hello") go say("World") wg.Wait() } ``` wg.add(2)是有2个goroutine需要执行 wg.Done 相当于 wg.Add(-1) 意思就是我这个协程执行完了。wg.Wait() 就是告诉主线程要等一下,等他们2个都执行完再退出 # 协程安全 非常经典的例子,两个协程函数,分别对同一个全局变量进行操作 按照我们预期的结果,应该是200万,但是多运行几次,会发现结果各不相同 这就是协程安全问题 ```Go package main import ( "fmt" "sync" ) var w = sync.WaitGroup{} var num = 0 func AddNum() { for i := 0; i < 1000000; i++ { num++ } w.Done() } func main() { w.Add(2) go AddNum() go AddNum() w.Wait() fmt.Println(num) } ``` 这种情况我们可以通过加锁进行解决,go语言中给我们通过了这个方法 ```Go package main import ( "fmt" "sync" ) var lock = sync.Mutex{} var w = sync.WaitGroup{} var num = 0 func AddNum() { lock.Lock() // 上锁 for i := 0; i < 1000000; i++ { num++ } lock.Unlock() // 解锁 w.Done() } func main() { w.Add(2) go AddNum() go AddNum() w.Wait() fmt.Println(num) } ```
1
1
上一篇:golang 接口
下一篇:go 信道
你觉得文章怎么样
发布评论
127 人参与,0 条评论