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

标签 go

大家好,我正在尝试向数据库发出多个请求,我发现按顺序同步执行这些请求非常慢,并且在等待每个请求完成时响应时间呈指数增长,这就是我目前所拥有的:

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/

相关文章:

json - 如何将 hit.Source 反序列化为 golang 中的结构

go - go1.13如何从go程序生成doc

go - 如何从JSON数组中删除元素而不删除Golang中的下一个元素

去reflect.MakeFunc。如何返回 err=nil 作为reflect.Value?

go - Websocket 在 Echo Framework 中向所有客户端发送消息

algorithm - 进行递归二分查找

android - `gomobile build` 和 `gomobile install` 抛出 "gomobile: EOF"

postgresql - DefaultServeMux 中的 SQL 给出错误

pointers - 在 Go 中修改结构中的结构 slice

go - 当我的 go.sum 已经以这种方式检查时,这个差异是什么?