dongyou6795 2015-11-22 03:32
浏览 20
已采纳

如何正确执行多个并发请求?

Hi guys I'm trying to make multiple requests to a database, and I found doing them in order synchronously is quite slow and exponentially increases response time while waiting for each request to finish, this is what I have so far:

var wg sync.WaitGroup
dbUsername := make(chan string, 1)
dbEmail := make(chan string, 1)

wg.Add(2)
go func(username chan string, waiter sync.WaitGroup) {
    defer waiter.Done()
    err = db.QueryRow("SELECT username FROM user WHERE username = ?", vals.Get("username")).Scan(&result)
    if err != nil {
        log.Println(err)
    }
}(dbUsername, wg)

go func(email chan string, waiter sync.WaitGroup) {
    defer waiter.Done()
    err = db.QueryRow("SELECT email FROM user WHERE email = ?", vals.Get("email")).Scan(&result)
    if err != nil {
        log.Println(err)
    }
}(dbEmail, wg)

wg.Wait()



if <-dbUsername != "" {
    formErrors = append(formErrors, "Username has already been taken.")
}
if <-dbEmail != "" {
    formErrors = append(formErrors, "Email has already been taken.")
}

but it doesn't seem to work correctly, I've followed the WaitGroup example to the dot, but it seems to hang on wg.Wait() and I'm not sure why. And is there a prettier way to do this or is what I have mocked up normal?

also small sub question:

is it possible to declare a buffered channel with var e.g. var blah chan string 1

  • 写回答

1条回答 默认 最新

  • douduiyun6125 2015-11-22 03:44
    关注

    You're passing in a copy of your WaitGroup to your two functions,

    Instead pass in a pointer, waiter *sync.WaitGroup, so your code that waits on the WaitGroup and the goroutines all operates on the same WaitGroup.

    This is also noted in the documentation:

    Values containing the types defined in this package should not be copied.

    However, in your case your goroutine functions can access the variables declared in the outer scope, so you don't need to pass in any arguments at all. You might not need the WaitGroup either, as receiving of <-dbUsername and <-dbEmail will anyway wait until the goroutines are done - as long as you make both your goroutines send a value on their respective channels. And you don't need buffered channels here either.

    As for this:

    is it possible to declare a buffered channel with var e.g. var blah chan string 1

    Yes, remember that channels need to be created using make()

    var blah chan string 
    blah = make(chan string, 1)
    

    Or var blah chan string = make(chan string, 1)

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 vmware exsi重置后的密码
  • ¥15 易盾点选的cb参数怎么解啊
  • ¥15 MATLAB运行显示错误,如何解决?
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容
  • ¥15 UE5#if WITH_EDITOR导致打包的功能不可用
  • ¥15 关于#stm32#的问题:CANOpen的PDO同步传输问题
  • ¥20 yolov5自定义Prune报错,如何解决?
  • ¥15 电磁场的matlab仿真
  • ¥15 mars2d在vue3中的引入问题