Go 知识点(01)— 主协程与子协程执行顺序
下面代码的输出结果是什么?
package mainimport ("fmt"
)func main() {for i := 0; i < 10; i++ {go func() {fmt.Println(i)}()}
}
运行该代码输出的结果是什么? 可能有以下答案
- 大概率什么都没有输出
原因是: 只要主协程也就是 main 进程执行完毕,其它的 Go 协程就会立即结束,主协程也就是 Go 程序是不会等待其它 Go 协程的,
而此时由于 for 循环启动的 Go 协程完全有可能还有运行,从而导致任何没有输出任何内容。
- 小概率有可能是 10 个 10
原因是: 假如 for 循坏启动的 10 个 协程在 main 协程执行完毕之前已运行,由于协程的调度需要一定的时间,而通常这个时间是大于
for 循坏的时间的,所以等 10 个协程启动的时候,for 循环已经执行到最后的变量 i=10 了,所以就会打印 10 个 10。
- 小概率有可能是乱序的 1 到 9 等
原因: 如果 Go 协程启动的时间较快,在 for 循环每执行到一个变量时该协程就会立即启动,那么就会打印 1 到 9 不等,最终原因
还是与 Go 协程的调度机制有关。
那么问题来了,如果想要让子协程执行完毕后退出,有什么办法呢?
我们可以使用 sync.WaitGroup
来实现,请看下面代码
func main() {var wg sync.WaitGroupfor i := 0; i < 10; i++ {wg.Add(1) // 每启动一个协程就加 1go func() {defer wg.Done() // 协程退出时自动减 1fmt.Println(i)}()}wg.Wait() // 等待所有协程执行完毕
}
输出结果为:
10
10
10
10
10
10
10
10
10
10
如果想要让其打印出 0,1,2,3,4 … 等,需要怎样修改代码呢?
只需要在调用协程函数的时候传入对应的变量就行,如下代码:
func main() {var wg sync.WaitGroupfor i := 0; i < 10; i++ {wg.Add(1)go func(n int) {defer wg.Done()fmt.Println(n)}(i) // 传入外面循环变量的值}wg.Wait()
}
参考:
https://mp.weixin.qq.com/s/gqqAazWUCp1ZtK7PebJe3g
Go 知识点(01)— 主协程与子协程执行顺序相关推荐
- java 主线程与子线程的执行顺序
记录一个面试问题,多线程中需要等子线程全部执行完成后再执行主线程 网上的方式 1.sleep()方式,这种做法不靠谱,不知道cpu到底哪个线程会拿到,不能使用 2.将子线程加入集合中(最好是线程安全的 ...
- c++ 等待子线程结束_python主线程与子线程的结束顺序
对于程序来说,如果主进程在子进程还未结束时就已经退出,那么Linux内核会将子进程的父进程ID改为1(也就是init进程),当子进程结束后会由init进程来回收该子进程. 主线程退出后子线程的状态依赖 ...
- python中and与or的执行顺序-关联子查询的执行顺序是什么
sql的编写顺序 select .. from .. where .. group by ..having .. order by .. sql的执行顺序 from .. where .. group ...
- mysql 子查询执行顺序_关联子查询的执行顺序是什么
sql的编写顺序 select .. from .. where .. group by ..having .. order by .. sql的执行顺序 from .. where .. group ...
- Vue父组件mounted执行完后再执行子组件mounted执行顺序问题
文章目录 一.vue加载顺序? 二.父组件和子组件 1.封装ip地址框 2.前端从数据库取数据并且赋值 bug 解决方案 一.vue加载顺序? 父组件 created 子组件 created 子组件 ...
- go 怎么等待所有的协程完成_优雅地等待子协程执行完毕
goroutine模拟了线程级别的返场的能力,但它的执行需要主协程给机会.一般的作法用sleep,chan阻塞,看起来让人不爽,本文介绍sync.WaitGroup 类型结合 defer 的特性,给出 ...
- 【Kotlin 协程】协程启动 ② ( 多协程控制 | launch 协程执行顺序控制 | Job#join() 函数 | async 协程执行顺序控制 | Deferred#await() 函数 )
文章目录 一.launch 协程执行顺序控制 二.async 协程执行顺序控制 三.完整代码 源码地址 : https://download.csdn.net/download/han1202012/ ...
- java 子线程退出_java – 在子线程完成执行之前主线程将退出吗?
我读了2篇文章 在上面的文章中,在"线程终止"段中,它在Red中声明"如果父线程终止,它的所有子线程也会终止". 在上面的文章中,该页面的最后一行指出" ...
- Go 知识点(10) — 子协程能否使用主协程变量
我们来看这样一个问题,在主协程中创建的变量,在子协程中能否使用?来看下面代码: func main() {s := "hello"fmt.Printf("s outsid ...
最新文章
- 解决sdk manager 下载API失败的问题
- ee可以有js吗 jvaa_DOTA每日节奏—EE乱选英雄被举报封号,这真的合理吗
- 苹果六电池_昆明苹果手机售后维修地址 昆明苹果手机维修哪家好?
- asp.net mvc使用的心得和问题的解决方法(陆续更新ing)
- c语言黄建灯第七章答案,c语言实训大纲.doc
- sublime text plugins
- input回车触发事件_JavaScript学习笔记(十五)-- Event事件(上)
- 图标字体化浅谈[转]
- Atitit 剪贴板数据类型 DataFlavor 目录 1. HtmlFlavor	1 1.1. allHtmlFlavor	1 1.2. selectionHtmlFlavor	1 1.3. fr
- python脚本(比较两个Excel表格的不同并标记)
- 蓝桥杯省赛——杨辉三角java
- 印象笔记导入html笔记,Evernote Importer|印象笔记导入
- python中pdfplumber解析pdf_Python教程:pdfplumber提取pdf中的表格数据
- 单链表之首尾相连,成对输出
- 雷达一维距离像怎么用matlab仿真出来,雷达目标识别之一维距离像的学习
- mysql 按每月自定天数统计数据
- 房贷收入证明是月供的几倍?
- 程序设计基础—什么是逻辑与、或、非关系?
- LiveData的使用和原理
- android手机变微软手机号码,微软Your Phone未来将能让你用电脑远程控制拨打Android手机电话...