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

时间:2015-11-22 03:32:12

标签: go

大家好我正在尝试向数据库发出多个请求,我发现按顺序执行这些请求非常慢并且在等待每个请求完成时指数增加响应时间,这是我到目前为止所做的: / p>

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声明缓冲频道,例如var blah chan string 1

1 个答案:

答案 0 :(得分:1)

您正在将WaitGroup的副本传递给您的两个职能部门

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

documentation

中也提到了这一点
  

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

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

至于此:

  

是否可以使用var声明一个缓冲的通道。 var blah chan string 1

是的,请记住需要使用make()

创建频道
var blah chan string 
blah = make(chan string, 1)

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