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 相关文章推荐
Golang 正则匹配效率详解
Apr 25 Golang
golang中实现给gif、png、jpeg图片添加文字水印
Apr 26 Golang
golang通过递归遍历生成树状结构的操作
Apr 28 Golang
golang 如何用反射reflect操作结构体
Apr 28 Golang
golang import自定义包方式
Apr 29 Golang
Golang 如何实现函数的任意类型传参
Apr 29 Golang
解决goland 导入项目后import里的包报红问题
May 06 Golang
go mod 安装依赖 unkown revision问题的解决方案
May 06 Golang
使用golang编写一个并发工作队列
May 08 Golang
Golang数据类型和相互转换
Apr 12 Golang
Golang Elasticsearches 批量修改查询及发送MQ
Apr 19 Golang
详解Go语言中Get/Post请求测试
Jun 01 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
聊天室php&amp;mysql(五)
2006/10/09 PHP
php模板中出现空行解决方法
2011/03/08 PHP
一个PHP缓存类代码(附详细说明)
2011/06/09 PHP
php 伪造本地文件包含漏洞的代码
2011/11/03 PHP
php 删除一个数组中的某个值.兼容多维数组!
2012/02/18 PHP
MyEclipse常用配置图文教程
2014/09/11 PHP
JQuery实现的在新窗口打开链接的方法小结
2010/04/22 Javascript
jQuery创建平滑的页面滚动(顶部或底部)
2013/02/26 Javascript
js字母大小写转换实现方法总结
2013/11/13 Javascript
jquery实现鼠标滑过小图时显示大图的方法
2015/01/14 Javascript
Node.js检测端口(port)是否被占用的简单示例
2016/09/29 Javascript
微信小程序 教程之条件渲染
2016/10/18 Javascript
nodejs连接mysql数据库简单封装示例-mysql模块
2017/04/10 NodeJs
详解AngularJS ng-class样式切换
2017/06/27 Javascript
Angular4开发解决跨域问题详解
2017/08/28 Javascript
基于vue-element组件实现音乐播放器功能
2018/05/06 Javascript
Vue父子组件双向绑定传值的实现方法
2018/07/31 Javascript
layui--js控制switch的切换方法
2019/09/03 Javascript
layui下拉框获取下拉值(select)的例子
2019/09/10 Javascript
JavaScript实现图片上传并预览并提交ajax
2019/09/30 Javascript
vue实现设置载入动画和初始化页面动画效果
2019/10/28 Javascript
vue  elementUI 表单嵌套验证的实例代码
2019/11/06 Javascript
JS字符串补全方法padStart()和padEnd()
2020/05/27 Javascript
[46:20]DOTA2-DPC中国联赛 正赛 PSG.LGD vs LBZS BO3 第二场 1月22日
2021/03/11 DOTA
总结Python编程中函数的使用要点
2016/03/20 Python
python 反向输出字符串的方法
2018/07/16 Python
Python读写zip压缩文件的方法
2018/08/29 Python
Python opencv实现人眼/人脸识别以及实时打码处理
2019/04/29 Python
导入tensorflow:ImportError: libcublas.so.9.0 报错
2020/01/06 Python
HTML5的结构和语义(1):前言
2008/10/17 HTML / CSS
鞋类设计与工艺专业销售求职信
2013/11/01 职场文书
市场营销毕业生自荐信范文
2014/04/01 职场文书
委托书怎么写
2014/07/31 职场文书
人口与计划生育责任书
2015/05/09 职场文书
盘点2020年适合农村地区创业的项目
2019/10/16 职场文书
解决vue $http的get和post请求跨域问题
2021/06/07 Vue.js