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 如何用反射reflect操作结构体
Apr 28 Golang
Golang 空map和未初始化map的注意事项说明
Apr 29 Golang
解决Golang time.Parse和time.Format的时区问题
Apr 29 Golang
Golang Gob编码(gob包的使用详解)
May 07 Golang
Go 在 MongoDB 中常用查询与修改的操作
May 07 Golang
入门学习Go的基本语法
Jul 07 Golang
go使用Gin框架利用阿里云实现短信验证码功能
Aug 04 Golang
简单聊聊Golang中defer预计算参数
Mar 25 Golang
golang操作rocketmq的示例代码
Apr 06 Golang
Golang流模式之grpc的四种数据流
Apr 13 Golang
golang的文件创建及读写操作
Apr 14 Golang
Golang map映射的用法
Apr 22 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数组函数序列之array_flip() 将数组键名与值对调
2011/11/07 PHP
php验证码实现代码(3种)
2015/09/07 PHP
smarty简单应用实例
2015/11/03 PHP
PHP7常量数组用法分析
2016/09/26 PHP
YII框架常用技巧总结
2019/04/27 PHP
jquery dialog键盘事件代码
2010/08/01 Javascript
jq选项卡鼠标延迟的插件实例
2013/05/13 Javascript
javascript代码运行不出来执行错误的可能情况整理
2013/10/18 Javascript
两种不同的方法实现js对checkbox进行全选和反选
2014/05/13 Javascript
jQuery中:visible选择器用法实例
2014/12/30 Javascript
jQuery自动添加表单项的方法
2015/07/13 Javascript
解决JS无法调用Controller问题的方法
2015/12/31 Javascript
jQuery获取多种input值的简单实现方法
2016/06/20 Javascript
Angularjs---项目搭建图文教程
2016/07/08 Javascript
NProgress显示顶部进度条效果及使用详解
2019/09/21 Javascript
Python设计模式之观察者模式简单示例
2018/01/10 Python
Python3导入CSV文件的实例(跟Python2有些许的不同)
2018/06/22 Python
python使用配置文件过程详解
2019/12/28 Python
PyTorch中model.zero_grad()和optimizer.zero_grad()用法
2020/06/24 Python
详解Anaconda 的安装教程
2020/09/23 Python
Spy++的使用方法及下载教程
2021/01/29 Python
Python Selenium异常处理的实例分析
2021/02/28 Python
Links of London官方网站:英国标志性的珠宝品牌
2017/04/09 全球购物
丹尼尔惠灵顿手表天猫官方旗舰店:Daniel Wellington
2017/08/25 全球购物
英国百年闻名的优质健康产品连锁店:Holland & Barrett
2019/12/19 全球购物
Java的类可以定义为Protected或者Private得吗
2015/09/25 面试题
四年的大学生生活自我评价
2013/12/09 职场文书
销售人员自我评价
2014/02/01 职场文书
学校节能宣传周活动总结
2014/07/09 职场文书
学习十八大的心得体会
2014/09/12 职场文书
辞职信怎么写
2015/02/27 职场文书
小学生教师节广播稿
2015/08/19 职场文书
Python中rapidjson参数校验实现
2021/07/25 Python
MySQL学习之基础命令实操总结
2022/03/19 MySQL
Pandas 数据编码的十种方法
2022/04/20 Python
win10忘记pin密码登录不了怎么办?win10忘记pin密码登不进去的解决方法
2022/07/07 数码科技