使用通道限制活动Go例程的数量

时间:2019-05-27 03:36:06

标签: go

我正在阅读“ The Go编程语言” 限制运行go例程数量的一种方法是使用“计数信号量”。

另一种方式是Limiting number of go routines running

在这种情况下,我允许再执行2个go例程。我遇到了死锁错误。 是什么导致我的代码陷入僵局?

package main

import (
    "bytes"
    //"context"
    "fmt"
    "runtime"
    "strconv"
    "sync"
    "time"
)

func main() {
    max := 2
    var wg sync.WaitGroup
    squares := make(chan int)
    tokens := make(chan struct{}, max)
    for i := 20; i >= 1; i-- {
        tokens <- struct{}{}
        wg.Add(1)
        go func(n int) {
            defer func() { <-tokens }()
            defer wg.Done()
            fmt.Println("run go routine ", getGID())
            squares <- Square(n)

        }(i)
    }

    go func() {
        wg.Wait()
        close(squares)
    }()

    for s := range squares {
        fmt.Println("Get square: ", s)

    }
}

func Square(num int) int {
    time.Sleep(time.Second * time.Duration(num))
    fmt.Println(num * num)
    return num * num
}

func getGID() uint64 {
    b := make([]byte, 64)
    b = b[:runtime.Stack(b, false)]
    b = bytes.TrimPrefix(b, []byte("goroutine "))
    b = b[:bytes.IndexByte(b, ' ')]
    n, _ := strconv.ParseUint(string(b), 10, 64)
    return n
}

1 个答案:

答案 0 :(得分:1)

goroutines在发送到export const loadList = (): ThunkResult => (dispatch: ThunkDispatcher) => { dispatch(/* start loading */); const result = await // load api call dispatch(loadListCreator(result)); } 时阻塞。 Main在export function loadReducer (state = initalState, action: AppActions) // reducer code 上未接收到,因为它阻止启动goroutine。

通过将启动goroutine的代码移动到goroutine进行修复。这允许main继续执行squares上的接收。

squares

Run it on the playground