我有一个 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) 我想添加并发性来迭代嵌套循环,但遇到了麻烦。这个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
正如您所看到的,它跳过两个数组的第一个元素并仅迭代最后一个元素。有什么想法可以解决此行为吗?
当一个错误发生时,如何阻止另一个错误?
\n\n我必须使用res1和res2\xef\xbc\x8cin生产res1,res2不是相同的静态类型。
\n\npackage 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}\nRun Code Online (Sandbox Code Playgroud)\n 我正在运行一个服务器,其中 main 触发几个 go 例程。像这样:
main() {
go someFn(){
// will run for infinite time()
}
go otherFn()
}
Run Code Online (Sandbox Code Playgroud)
我有两个疑问:
如果main函数退出了怎么办?这些线程是否仍然会运行或者会随着 main 函数而终止?
如果不是,那么让主函数永远运行/或运行直到我需要它的最佳方法是什么?目前,我正在使用select{}命令使其永远运行!有没有比这更好、更有效的方法select{}
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 DelegateWork(mr, <-mr.impl.readyWorkers, jobArgs)
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,通道接收操作符是否会导致调用者或被调用的 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 没有检测到它,并且根据经验,我无法让它恐慌。
除了维基百科https://en.wikipedia.org/wiki/Channel_(programming) 的解释之外,我找不到关于这个问题的任何信息。但我对解释不满意。
渠道解决什么问题?为什么我们不直接使用普通变量来发送和接收数据呢?
今天,我了解了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) 我对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)