Go N个协程交替打印1-100

package main

import (
    "fmt"
    "runtime"
)

func main() {
    goroutine := runtime.NumCPU()
    chanSlice := make([]chan struct{}, 0)
    chanExit := make(chan struct{}, 1)

    for i := 0; i < goroutine; i++ {
        chanSlice = append(chanSlice, make(chan struct{}, 1))
    }

    max := 100
    num := 0

    fmt.Println("runtime.NumCPU(): ", runtime.NumCPU())

    for i := 0; i < goroutine; i++ {
        go func(x int) {
            for {
                <-chanSlice[x]
                num++
                fmt.Println("goroutine: ", x, " chan: ", chanSlice[x], " num: ", num)

                if num == max {
                    chanExit <- struct{}{}
                    break
                }

                chanSlice[(x+1)%goroutine] <- struct{}{}
            }
        }(i)
    }

    chanSlice[0] <- struct{}{}

    select {
    case <-chanExit:
        fmt.Println("exit")
    }

    fmt.Println("goroutine: ", runtime.NumGoroutine())
}

Run on Go Playground

改造下:

package main

import (
    "fmt"
    "runtime"
    "sync"
)

func main() {
    var wg sync.WaitGroup
    goroutine := runtime.NumCPU()
    chanSlice := make([]chan struct{}, 0)
    chanExit := make(chan struct{}, 1)

    for i := 0; i < goroutine; i++ {
        chanSlice = append(chanSlice, make(chan struct{}, 1))
    }

    max := 100
    num := 0

    fmt.Println("runtime.NumCPU(): ", runtime.NumCPU())

    for i := 0; i < goroutine; i++ {
        wg.Add(1)
        go func(x int) {
            defer wg.Done()
            defer fmt.Println("exit goroutine: ", x)
            for {
                select {
                case <-chanExit:
                    // close the next goroutine
                    chanExit <- struct{}{}
                    return

                case <-chanSlice[x]:
                    num++
                    fmt.Println("goroutine: ", x, " chan: ", chanSlice[x], " num: ", num)

                    if num == max {
                        chanExit <- struct{}{}
                        break
                    }
                    chanSlice[(x+1)%goroutine] <- struct{}{}
                }
            }
        }(i)
    }

    // start
    chanSlice[0] <- struct{}{}
    wg.Wait()

    fmt.Println("goroutine: ", runtime.NumGoroutine())
}

Run on Go Playground

添加新评论