为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
忽然笑 2021-11-22 18:35:24
我正在尝试向数据库发出多个请求,我发现同步执行这些请求非常慢,并且在等待每个请求完成时响应时间呈指数增长,这就是我到目前为止所拥有的:var wg sync.WaitGroupdbUsername := 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例如var blah chan string 1
查看完整描述

1 回答

?
红糖糍粑

TA贡献1815条经验 获得超6个赞

您正在将您的副本传递WaitGroup给您的两个函数,

而是传入一个指针, waiter *sync.WaitGroup,因此您在 WaitGroup 上等待的代码和 goroutine 都在同一个 WaitGroup 上运行。

这也在文档中注明:

不应复制包含在此包中定义的类型的值。

但是,在您的情况下,您的 goroutine 函数可以访问在外部作用域中声明的变量,因此您根本不需要传入任何参数。您可能也不需要 WaitGroup,因为接收<-dbUsername 并且<-dbEmail无论如何都会等到 goroutine 完成 - 只要您让您的两个 goroutine 在各自的通道上发送一个值。而且您也不需要这里的缓冲通道。

至于这个:

是否可以使用 var 声明缓冲通道,例如 var blah chan string 1

是的,请记住需要使用创建频道 make()

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

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


查看完整回答
反对 回复 2021-11-22
  • 1 回答
  • 0 关注
  • 155 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信