golang goroutine順序輸出方式
range字符串,使用goroutine打印
因?yàn)間oroutine隨機(jī)執(zhí)行
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
補(bǔ)充:golang goroutine順序循環(huán)打印ABC
分別使用sync.WaitGroup和context
使用sync.WaitGroup, 可控制循環(huán)次數(shù)
package main
import (
"fmt"
"sync"
)
//控制循環(huán)次數(shù)
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,通過(guò)time.Sleep控制打印數(shù)量
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") // 不會(huì)輸出
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") // 不會(huì)輸出
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") // 不會(huì)輸出
return
case <-chanC:
fmt.Println("C")
chanA <- struct{}{}
}
}
}
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
- Go語(yǔ)言輕量級(jí)線(xiàn)程Goroutine用法實(shí)例
- golang gin 框架 異步同步 goroutine 并發(fā)操作
- go獲取協(xié)程(goroutine)號(hào)的實(shí)例
- go中控制goroutine數(shù)量的方法
- GoLang使goroutine停止的五種方法實(shí)例
- 詳解Go語(yǔ)言中Goroutine退出機(jī)制的原理及使用
- Golang 探索對(duì)Goroutine的控制方法(詳解)
- Go 防止 goroutine 泄露的方法
- 一文帶你搞懂Golang如何正確退出Goroutine
- 深入理解 Go 協(xié)程 Goroutine的實(shí)現(xiàn)
相關(guān)文章
go語(yǔ)言題解LeetCode228匯總區(qū)間示例詳解
這篇文章主要為大家介紹了go語(yǔ)言題解LeetCode228匯總區(qū)間示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
go 迭代string數(shù)組操作 go for string[]
這篇文章主要介紹了go 迭代string數(shù)組操作 go for string[],具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12
GoZero中make后返回?cái)?shù)據(jù)與原數(shù)據(jù)不對(duì)齊的幾種解決方案
在Go語(yǔ)言中,make是用來(lái)創(chuàng)建切片、映射(map)和通道(channel)的內(nèi)建函數(shù),但是,在使用 make 創(chuàng)建切片時(shí),若不理解如何正確使用其返回值,可能會(huì)遇到數(shù)據(jù)對(duì)不上或結(jié)果不符合預(yù)期的情況,本文將分析在GoZero或其他基于Go的應(yīng)用中,使用make時(shí)可能導(dǎo)致的問(wèn)題及解決方案2025-01-01
詳解Go中Map類(lèi)型和Slice類(lèi)型的傳遞
這篇文章主要為大家詳細(xì)介紹了Go中Map類(lèi)型和Slice類(lèi)型的傳遞,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11
GoRoutines高性能同時(shí)進(jìn)行多個(gè)Api調(diào)用實(shí)現(xiàn)
這篇文章主要為大家介紹了GoRoutines高性能同時(shí)進(jìn)行多個(gè)Api調(diào)用實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03

