标签: goroutine

golang 中 server.GracefulStop() 的行为

我有一个 gRPC 服务器,并且我已经实现了 gRPC 服务器的正常关闭,如下所示

fun main() {
    //Some code
    term := make(chan os.Signal)
    go func() {
            if err := grpcServer.Serve(lis); err != nil {
                term <- syscall.SIGINT
            }
        }()

    signal.Notify(term, syscall.SIGTERM, syscall.SIGINT)
    <-term
    server.GracefulStop()
    closeDbConnections()
}
Run Code Online (Sandbox Code Playgroud)

这很好用。如果我grpcServer.Serve()在主 goroutine 中编写逻辑,并将关闭处理程序逻辑放入另一个 goroutine 中,则之后的语句server.GracefulStop()通常不会执行。一些 DbConnections 如果closeDbConnections()执行的话,会被关闭。

server.GracefulStop()是一个阻塞调用。绝对在完成grpcServer.Serve()之前完成server.GracefulStop()。那么,在这个调用返回后,main goroutine 需要多长时间才能停止呢?

有问题的代码

func main() {
    term := make(chan os.Signal)
    go func() {
        signal.Notify(term, syscall.SIGTERM, syscall.SIGINT)
        <-term
        server.GracefulStop()
        closeDbConnections()
    }()
    if err := grpcServer.Serve(lis); …
Run Code Online (Sandbox Code Playgroud)

go goroutine server grpc grpc-go

0
推荐指数
1
解决办法
6177
查看次数

sync.WaitGroup 和嵌套循环

我想添加并发性来迭代嵌套循环,但遇到了麻烦。这个sync.WaitGroup 的示例用法有什么问题?

originCities := [3]string{"LED", "MOW", "PRS"}
destinationCities := [2]string{"UKT", "AAC"}

wg := &sync.WaitGroup{}
wg.Add(len(originCities) * len(destinationCities))

for _, originIata := range originCities {
    for _, destinationIata := range destinationCities {
        go func () {
            fmt.Println(originIata)
            fmt.Println(destinationIata)
            wg.Done()
        }()
    }
}
wg.Wait()
Run Code Online (Sandbox Code Playgroud)

我越来越

PRS AAC PRS AAC PRS AAC PRS AAC PRS AAC PRS AAC

正如您所看到的,它跳过两个数组的第一个元素并仅迭代最后一个元素。有什么想法可以解决此行为吗?

go goroutine

0
推荐指数
1
解决办法
4193
查看次数

发生错误时如何停止 goroutine

当一个错误发生时,如何阻止另一个错误?

\n\n

我必须使用res1和res2\xef\xbc\x8cin生产res1,res2不是相同的静态类型。

\n\n
package main\n\nimport (\n    "fmt"\n    "net/http"\n    "sync"\n)\n\nfunc main() {\n    wg := &sync.WaitGroup{}\n    wg.Add(2)\n\n    var res1, res2 *http.Response\n    var err1, err2 error\n\n    go func() {\n        defer wg.Done()\n        res1, err1 = http.Get("http://127.0.0.1:8899")\n        if err1 != nil {\n            panic(err1)\n        }\n    }()\n    go func() {\n        defer wg.Done()\n        res2, err2 = http.Get("http://127.0.0.1:8898")\n        if err2 != nil {\n            panic(err2)\n        }\n    }()\n    wg.Wait()\n\n    fmt.Println(res1, res2)\n}\n
Run Code Online (Sandbox Code Playgroud)\n

go goroutine

0
推荐指数
1
解决办法
567
查看次数

即使 main 函数终止,goroutines 也会继续运行吗?

我正在运行一个服务器,其中 main 触发几个 go 例程。像这样:

main() {
     go someFn(){
       // will run for infinite time()
     }
     go otherFn()
}
Run Code Online (Sandbox Code Playgroud)

我有两个疑问:

  1. 如果main函数退出了怎么办?这些线程是否仍然会运行或者会随着 main 函数而终止?

  2. 如果不是,那么让主函数永远运行/或运行直到我需要它的最佳方法是什么?目前,我正在使用select{}命令使其永远运行!有没有比这更好、更有效的方法select{}

multithreading go goroutine

0
推荐指数
1
解决办法
4710
查看次数

如何设置完成工作的最大 goroutine 数量?

var wg sync.WaitGroup
wg.Add(len(work))

sem := make(chan struct{}, 10)

wgDone := make(chan bool)

for i < len(work)-1 {
    go func() {
        defer wg.Done()
        sem <- struct{}{}
        defer func() {
            <-sem
        }()
        worker(work[i])
    }()
    i = i + 1
}

go func() {     
    wg.Wait()
    close(wgDone)
}()
Run Code Online (Sandbox Code Playgroud)

我一次只需要10 个新的 goroutine来执行这项工作。这是我当前的解决方案,它阻止 goroutine 继续运行,因此一次只有 10 个。我怎样才能改变这个,这样它就不会创建大量被阻塞等待工作的 goroutine,而是只创建 10 个完成所有工作的 goroutine?

go goroutine

0
推荐指数
1
解决办法
4850
查看次数

goroutine调用中通道接收操作符的阻塞行为

go DelegateWork(mr, <-mr.impl.readyWorkers, jobArgs)    
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,通道接收操作符是否会导致调用者或被调用的 goroutine 阻塞?

channel go goroutine

0
推荐指数
1
解决办法
54
查看次数

是否可以使用 select 从多个 goroutine 中安全地关闭一次通道?

我的解决方案如下,但是以下代码中是否存在竞争条件(它会出现恐慌)吗?

c := make(chan struct{})

for i := 0; i < 1000000; i++ {
    go func() {
        select {
        case <-c:
        default:
            close(c)
        }
    }()
}
Run Code Online (Sandbox Code Playgroud)

我认为是的,但是 go test -race 没有检测到它,并且根据经验,我无法让它恐慌。

concurrency channel go goroutine

0
推荐指数
1
解决办法
128
查看次数

为什么 Go 使用通道在 goroutine 之间发送和接收数据而不是使用普通变量?

除了维基百科https://en.wikipedia.org/wiki/Channel_(programming) 的解释之外,我找不到关于这个问题的任何信息。但我对解释不满意。

渠道解决什么问题?为什么我们不直接使用普通变量来发送和接收数据呢?

go goroutine

0
推荐指数
1
解决办法
120
查看次数

Go goroutine 没有运行

今天,我了解了buffered channels. 我面临的问题是,我正在使用 WaitGroup 的Wait函数来执行所有 goroutine。

但并不是所有的 goroutine 都在执行,程序在没有等待所有 goroutine 完成的情况下就结束了。

代码:

func main() {
    
    // initializing a WaitGroup
    var wg sync.WaitGroup

    // adding 3 counts/buffer to the WaitGroup
    wg.Add(3)
    
    fmt.Println("Start Goroutines")
    go responseSize("https://www.golangprograms.com", &wg)
    go responseSize("https://stackoverflow.com", &wg)
    go responseSize("https://coderwall.com", &wg)

    // wait for goroutines to finish
    wg.Wait()
    fmt.Println("Terminating the main program")

}

// just prints the response size of the body returned 
func responseSize(url string, wg *sync.WaitGroup) {
    // schedule the Done() call when the …
Run Code Online (Sandbox Code Playgroud)

concurrency go goroutine

0
推荐指数
1
解决办法
69
查看次数

如何让Go通道工作者有不同的结果长度?

我对gobyexample做了一些编辑:

import (
    "fmt"
    "math/rand"
    "time"
)

type DemoResult struct {
    Name string
    Rate int
}

func random(min, max int) int {
    rand.Seed(time.Now().UTC().UnixNano())
    return rand.Intn(max-min) + min
}

func worker(id int, jobs <-chan int, results chan<- DemoResult) {
    for j := range jobs {
        fmt.Println("worker", id, "started  job", j)
        time.Sleep(time.Second)
        fmt.Println("worker", id, "finished job", j)
        myrand := random(1, 4)
        if myrand == 2 {
            results <- DemoResult{Name: "succ", Rate: j}
        }
        //  else {
        //  results <- DemoResult{Name: "failed", …
Run Code Online (Sandbox Code Playgroud)

go goroutine

0
推荐指数
1
解决办法
125
查看次数

标签 统计

go ×10

goroutine ×10

channel ×2

concurrency ×2

grpc ×1

grpc-go ×1

multithreading ×1

server ×1