大家好,我正在尝试向数据库发出多个请求,我发现按顺序同步执行这些请求非常慢,并且在等待每个请求完成时响应时间呈指数增长,这就是我目前所拥有的:
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.")
}
但它似乎无法正常工作,我已经按照 WaitGroup
示例进行了操作,但它似乎卡在 wg.Wait()
上并且我不确定为什么。有没有更漂亮的方法来做到这一点,或者我模拟的是正常的?
也是小子问题:
是否可以使用 var
声明缓冲 channel ,例如var blah chan 字符串 1
最佳答案
您正在传递您的 WaitGroup
的副本到你的两个功能,
而是传入一个指针,waiter *sync.WaitGroup
,所以等待 WaitGroup 的代码和 goroutines 都在同一个 WaitGroup 上运行。
documentation 中也注明了这一点:
Values containing the types defined in this package should not be copied.
但是,在您的情况下,您的 goroutine 函数可以访问在外部作用域中声明的变量,因此您根本不需要传入任何参数。您可能也不需要 WaitGroup,因为收到 <-dbUsername
和 <-dbEmail
无论如何都会等到 goroutines 完成 - 只要你让你的 goroutines 在各自的 channel 上发送一个值。而且您在这里也不需要缓冲 channel 。
至于这个:
is it possible to declare a buffered channel with var e.g. var blah chan string 1
是的,请记住需要使用 make()
创建 channel
var blah chan string
blah = make(chan string, 1)
或var blah chan string = make(chan string, 1)
关于go - 如何正确执行多个并发请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33851312/