golang goroutine顺序输出方式


Posted in Golang onApril 29, 2021

range字符串,使用goroutine打印

因为goroutine随机执行

for _, v := range str {
        go func() {
            fmt.Println(string(v))
        }()
}

输出:

5

5

5

5

5

可以使用chan顺序输出

for  _, c := range str{
        ch := make(chan rune)
        go func(ch <-chan rune) {
            key := <-ch
            fmt.Println(string(key))
        }(ch)
        ch <- c
    }

输出:

1

2

3

4

5

补充:golang goroutine顺序循环打印ABC

分别使用sync.WaitGroup和context

使用sync.WaitGroup, 可控制循环次数

package main
import (
	"fmt"
	"sync"
)
//控制循环次数
var count = 5
func main() {
	wg := sync.WaitGroup{}
	chanA := make(chan struct{}, 1)
	chanB := make(chan struct{}, 1)
	chanC := make(chan struct{}, 1)
	chanA <- struct{}{}
	wg.Add(3)
	go printA(&wg, chanA, chanB)
	go printB(&wg, chanB, chanC)
	go printC(&wg, chanC, chanA)
	wg.Wait()
}
func printA(wg *sync.WaitGroup, chanA, chanB chan struct{}) {
	defer wg.Done()
	for i := 0; i < count; i++ {
		<-chanA
		fmt.Println("A")
		chanB <- struct{}{}
	}
}
func printB(wg *sync.WaitGroup, chanB, chanC chan struct{}) {
	defer wg.Done()
	for i := 0; i < count; i++ {
		<-chanB
		fmt.Println("B")
		chanC <- struct{}{}
	}
}
func printC(wg *sync.WaitGroup, chanC, chanA chan struct{}) {
	defer wg.Done()
	for i := 0; i < count; i++ {
		<-chanC
		fmt.Println("C")
		chanA <- struct{}{}
	}
}

使用context.WithCancel,通过time.Sleep控制打印数量

package main
import (
	"context"
	"fmt"
	"time"
)
func main() {
	chanA := make(chan struct{}, 1)
	chanB := make(chan struct{}, 1)
	chanC := make(chan struct{}, 1)
	chanA <- struct{}{}
	ctx1, cancel1 := context.WithCancel(context.Background())
	ctx2, cancel2 := context.WithCancel(context.Background())
	ctx3, cancel3 := context.WithCancel(context.Background())
	go printA(ctx1, chanA, chanB)
	go printB(ctx2, chanB, chanC)
	go printC(ctx3, chanC, chanA)
	time.Sleep(100 * time.Microsecond)
	cancel1()
	cancel2()
	cancel3()
}
func printA(ctx context.Context, chanA, chanB chan struct{}) {
	for {
		select {
		case <-ctx.Done():
			fmt.Println("cancel by parent") // 不会输出
			return
		case <-chanA:
			fmt.Println("A")
			chanB <- struct{}{}
		}
	}
}
func printB(ctx context.Context, chanB, chanC chan struct{}) {
	for {
		select {
		case <-ctx.Done():
			fmt.Println("cancel by parent") // 不会输出
			return
		case <-chanB:
			fmt.Println("B")
			chanC <- struct{}{}
		}
	}
}
func printC(ctx context.Context, chanC, chanA chan struct{}) {
	for {
		select {
		case <-ctx.Done():
			fmt.Println("cancel by parent") // 不会输出
			return
		case <-chanC:
			fmt.Println("C")
			chanA <- struct{}{}
		}
	}
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。如有错误或未考虑完全的地方,望不吝赐教。

Golang 相关文章推荐
为什么不建议在go项目中使用init()
Apr 12 Golang
golang 如何用反射reflect操作结构体
Apr 28 Golang
golang slice元素去重操作
Apr 30 Golang
解决Golang中goroutine执行速度的问题
May 02 Golang
Golang生成Excel文档的方法步骤
Jun 09 Golang
Go语言基础知识点介绍
Jul 04 Golang
Golang使用Panic与Recover进行错误捕获
Mar 22 Golang
golang三种设计模式之简单工厂、方法工厂和抽象工厂
Apr 10 Golang
Golang 遍历二叉树
Apr 19 Golang
Golang实现可重入锁的示例代码
May 25 Golang
Go结合Gin导出Mysql数据到Excel表格
Aug 05 Golang
Go gorilla/sessions库安装使用
Aug 14 Golang
golang 在windows中设置环境变量的操作
解决golang在import自己的包报错的问题
golang import自定义包方式
golang 接口嵌套实现复用的操作
Apr 29 #Golang
浅谈Golang 嵌套 interface 的赋值问题
Apr 29 #Golang
Go 实现英尺和米的简单单位换算方式
Apr 29 #Golang
Golang 空map和未初始化map的注意事项说明
You might like
2020年4月放送!《Princess Connect Re:Dive》制作组 & 角色声优公开!
2020/03/06 日漫
ThinkPHP无限级分类原理实现留言与回复功能实例
2014/10/31 PHP
wordpress安装过程中遇到中文乱码的处理方法
2015/04/21 PHP
$(document).ready(function() {})不执行初始化脚本
2014/06/19 Javascript
javascript基于HTML5 canvas制作画箭头组件
2014/06/25 Javascript
基于jquery实现的自动补全功能
2015/03/12 Javascript
flash+jQuery实现可关闭及重复播放的压顶广告
2015/04/15 Javascript
JavaScript实现Flash炫光波动特效
2015/05/14 Javascript
分享js粘帖屏幕截图到web页面插件screenshot-paste
2020/08/21 Javascript
bootstrap模态框垂直居中效果
2016/12/03 Javascript
深入理解JavaScript中的for循环
2017/02/07 Javascript
Vue 2.0 服务端渲染入门介绍
2017/03/29 Javascript
详解Nodejs之npm&amp;package.json
2017/06/15 NodeJs
Node.js使用Express.Router的方法
2017/11/14 Javascript
JS计算距当前时间的时间差实例
2017/12/29 Javascript
p5.js入门教程之平滑过渡(Easing)
2018/03/16 Javascript
vue项目中使用Hbuilder打包app 设置沉浸式状态栏的方法
2018/10/22 Javascript
JavaScript实现的滚动公告特效【基于jQuery】
2019/07/10 jQuery
JS highcharts实现动态曲线代码示例
2020/10/16 Javascript
微信小程序实现多行文字滚动
2020/11/18 Javascript
[02:40]DOTA2英雄基础教程 炼金术士
2013/12/23 DOTA
Python两个内置函数 locals 和globals(学习笔记)
2016/08/28 Python
Python爬虫代理IP池实现方法
2017/01/05 Python
python 获取网页编码方式实现代码
2017/03/11 Python
基于python(urlparse)模板的使用方法总结
2017/10/13 Python
使用Python进行AES加密和解密的示例代码
2018/02/02 Python
numpy.ndarray 交换多维数组(矩阵)的行/列方法
2018/08/02 Python
python接口自动化测试之接口数据依赖的实现方法
2019/04/26 Python
Python中类似于jquery的pyquery库用法分析
2019/12/02 Python
基于python和flask实现http接口过程解析
2020/06/15 Python
Python return语句如何实现结果返回调用
2020/10/15 Python
kmart凯马特官网:美国最大的打折零售商和全球最大的批发商之一
2016/11/17 全球购物
萨克斯第五大道精品百货店: Saks Fifth Avenue
2017/04/28 全球购物
英国乐购杂货:Tesco Groceries
2018/11/29 全球购物
2015年学校远程教育工作总结
2015/07/20 职场文书
班主任工作总结范文
2015/08/13 职场文书