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中字符串MD5生成方式总结
Jul 04 Golang
Go语言基础切片的创建及初始化示例详解
Nov 17 Golang
Golang 并发下的问题定位及解决方案
Mar 16 Golang
简单聊聊Golang中defer预计算参数
Mar 25 Golang
Golang数据类型和相互转换
Apr 12 Golang
Go语言 详解net的tcp服务
Apr 14 Golang
golang用type-switch判断interface的实际存储类型
Apr 14 Golang
GO语言字符串处理函数之处理Strings包
Apr 14 Golang
Go获取两个时区的时间差
Apr 20 Golang
Golang并发工具Singleflight
May 06 Golang
Go web入门Go pongo2模板引擎
May 20 Golang
Go调用Rust方法及外部函数接口前置
Jun 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
德生S2000收音机更换“钕铁硼”全频扬声器
2021/03/02 无线电
发挥语言的威力--融合PHP与ASP
2006/10/09 PHP
根据key删除数组中指定的元素实现方法
2017/03/02 PHP
Laravel使用消息队列需要注意的一些问题
2017/12/13 PHP
thinkPHP框架实现的无限回复评论功能示例
2018/06/09 PHP
PHP常用函数之格式化时间操作示例
2019/10/21 PHP
PHP序列化和反序列化深度剖析实例讲解
2020/12/29 PHP
JavaScript让IE浏览器event对象符合W3C DOM标准
2009/11/24 Javascript
jQuery获得指定元素坐标的方法
2015/04/14 Javascript
JS实现模拟百度搜索“2012世界末日”网页地震撕裂效果代码
2015/10/31 Javascript
js中substring和substr两者区别和使用方法
2015/11/09 Javascript
Bootstrap每天必学之表单
2015/11/23 Javascript
D3.js实现文本的换行详解
2016/10/14 Javascript
Bootstrap的popover(弹出框)2秒后定时消失的实现代码
2017/02/27 Javascript
JS获取子、父、兄节点方法小结
2017/08/14 Javascript
js中如何完美的解析数据
2018/03/18 Javascript
浅谈layer的Icon样式以及一些常用的layer窗口使用方法
2019/09/11 Javascript
NUXT SSR初级入门笔记(小结)
2019/12/16 Javascript
vue+vant实现商品列表批量倒计时功能
2020/01/13 Javascript
js实现简易ATM功能
2020/10/27 Javascript
[48:51]完美世界DOTA2联赛PWL S2 Magma vs InkIce 第一场 11.28
2020/12/02 DOTA
python 基础学习第二弹 类属性和实例属性
2012/08/27 Python
使用python将mdb数据库文件导入postgresql数据库示例
2014/02/17 Python
python入门前的第一课 python怎样入门
2018/03/06 Python
python使用Flask操作mysql实现登录功能
2018/05/14 Python
Django中create和save方法的不同
2019/08/13 Python
python计算n的阶乘的方法代码
2019/10/25 Python
python GUI库图形界面开发之PyQt5选项卡控件QTabWidget详细使用方法与实例
2020/03/01 Python
python产生模拟数据faker库的使用详解
2020/11/04 Python
html5 canvas 简单画板实现代码
2012/01/05 HTML / CSS
安全员岗位职责
2015/02/10 职场文书
2015年护士节慰问信
2015/03/23 职场文书
八年级作文之一起的走过日子
2019/09/17 职场文书
解决numpy和torch数据类型转化的问题
2021/05/23 Python
Python 居然可以在 Excel 中画画你知道吗
2022/02/15 Python
React自定义hook的方法
2022/06/25 Javascript