登录
首页 >  Golang >  Go问答

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

来源:stackoverflow

时间:2024-03-08 13:39:25 176浏览 收藏

欢迎各位小伙伴来到golang学习网,相聚于此都是缘哈哈哈!今天我给大家带来《限制Go例程的数量:使用通道》,这篇文章主要讲到等等知识,如果你对Golang相关的知识非常感兴趣或者正在自学,都可以关注我,我会持续更新相关文章!当然,有什么建议也欢迎在评论留言提出!一起学习!

问题内容

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

另一种方法是限制运行的 go 例程数量

我允许在这种情况下再执行 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
}

解决方案


goroutine 阻止发送到 squares。 main 未在 squares 上接收,因为它在启动 goroutine 时受阻。

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

squares := make(chan int)
go func() {
    max := 2
    var wg sync.WaitGroup
    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)
    }

    wg.Wait()
    close(squares)
}()

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

}

Run it on the playground

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>