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)

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

报告相同问题?

悬赏问题

  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改