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各时间字符串使用解析
Apr 02 Golang
golang正则之命名分组方式
Apr 25 Golang
Golang 实现超大文件读取的两种方法
Apr 27 Golang
go语言中json数据的读取和写出操作
Apr 28 Golang
golang 实现两个结构体复制字段
Apr 28 Golang
Go语言中break label与goto label的区别
Apr 28 Golang
Go 实现英尺和米的简单单位换算方式
Apr 29 Golang
Golang 编译成DLL文件的操作
May 06 Golang
golang fmt格式“占位符”的实例用法详解
Jul 04 Golang
基于Go语言构建RESTful API服务
Jul 25 Golang
手把手教你导入Go语言第三方库
Aug 04 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批量添加数据与批量更新数据的实现方法
2014/12/16 PHP
PHP实现基于PDO扩展连接PostgreSQL对象关系数据库示例
2018/03/31 PHP
PHP进阶学习之垃圾回收机制详解
2019/06/18 PHP
js自带函数备忘 数组
2006/12/29 Javascript
javascript引用对象的方法
2007/01/11 Javascript
js实现DIV的一些简单控制
2007/06/04 Javascript
jQuery easyui datagrid动态查询数据实例讲解
2013/02/26 Javascript
实测jquery data()如何存值
2013/08/18 Javascript
JS实现图片横向滚动效果示例代码
2013/09/04 Javascript
js 日期比较相关天数代码
2014/04/02 Javascript
AngularJS中的Directive自定义一个表格
2016/01/25 Javascript
DOM操作原生js 的bug,使用jQuery 可以消除的解决方法
2016/09/04 Javascript
移动端使用localResizeIMG4压缩图片
2017/04/22 Javascript
详解原生js实现offset方法
2017/06/15 Javascript
JS移动端/H5同时选择多张图片上传并使用canvas压缩图片
2017/06/20 Javascript
vue路由跳转时判断用户是否登录功能的实现
2017/10/26 Javascript
JavaScript指定断点操作实例教程
2018/09/18 Javascript
详解Axios 如何取消已发送的请求
2018/10/20 Javascript
vue+axios 前端实现登录拦截的两种方式(路由拦截、http拦截)
2018/10/24 Javascript
vue学习笔记五:在vue项目里面使用引入公共方法详解
2019/04/04 Javascript
Vue中对iframe实现keep alive无刷新的方法
2019/07/23 Javascript
微信小程序的授权实现过程解析
2019/08/02 Javascript
解决angular 使用原生拖拽页面卡顿及表单控件输入延迟问题
2020/04/21 Javascript
vue操作dom元素的3种方法示例
2020/09/20 Javascript
Python中endswith()函数的基本使用
2015/04/07 Python
15行Python代码带你轻松理解令牌桶算法
2018/03/21 Python
Python表达式的优先级详解
2020/02/18 Python
python手机号前7位归属地爬虫代码实例
2020/03/31 Python
HTML5新增的Css选择器、伪类介绍
2013/08/07 HTML / CSS
瑞士图书网站:Weltbild.ch
2019/09/17 全球购物
2015年技术员工作总结
2015/04/10 职场文书
Vue如何实现组件间通信
2021/05/15 Vue.js
详解MySQL中的主键与事务
2021/05/27 MySQL
html中显示特殊符号(附带特殊字符对应表)
2021/06/21 HTML / CSS
python not运算符的实例用法
2021/06/30 Python
手写实现JS中的new
2021/11/07 Javascript