当前位置 博文首页 > golang goroutine顺序输出方式

    golang goroutine顺序输出方式

    作者:浩闻城 时间:2021-05-31 17:57

    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{}{}
    		}
    	}
    }
    

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持站长博客。如有错误或未考虑完全的地方,望不吝赐教。

    js
    下一篇:没有了