gpt4 book ai didi

http - Webhook 进程在另一个 goroutine 上运行

转载 作者:IT王子 更新时间:2023-10-29 01:21:21 26 4
gpt4 key购买 nike

我想在另一个 goroutine 中运行一些慢程序,这样做安全吗:

func someHandler(w http.ResponseWriter, r *http.Request) {
go someReallySlowFunction() // sending mail or something slow
fmt.Fprintf(w,"Mail will be delivered shortly..")
}

func otherHandler(w http.ResponseWriter, r *http.Request) {
foo := int64(0)
bar := func() {
// do slow things with foo
}
go bar()
fmt.Fprintf(w,"Mail will be delivered shortly..")
}

这样做有什么陷阱吗?

最佳答案

为每个 http 请求提供服务在其自己的 goroutine (more details on this) 中运行。您可以从处理程序启动新的 goroutine,它们将同时运行,独立于执行处理程序的 goroutine。

注意事项:

  • 新的 goroutine 独立于 handler goroutine 运行。这意味着它可能在处理程序 goroutine 之前或之后完成,如果没有显式同步,您不能(不应该)假设任何与此相关的事情。

  • http.ResponseWriterhttp.Request处理程序的参数只有在处理程序返回之前才有效且可以安全使用!这些值(或它们的“部分”)可以重复使用——这是一个实现细节,您也不应该假设任何东西。处理程序返回后,您不应触摸(甚至不读取)这些值。

  • 处理程序返回后,将提交响应(或可能随时提交)。这意味着您的新 goroutine 不应在此之后尝试使用 http.ResponseWriter 发回任何数据。这是真实的,即使您没有触摸处理程序中的 http.ResponseWriter,处理程序没有 panic 也被视为成功处理了请求,因此发送了 HTTP 200 状态返回(see an example of this)。

您可以将 http.Requesthttp.ResponseWriter 值传递给其他函数和新的 goroutine,但必须小心:您应该使用显式同步(例如锁、 channel )如果你打算从多个 goroutines 读取/修改这些值(或者你想从多个 goroutines 发回数据)。

请注意,如果您的处理程序 goroutine 和您的新 goroutine 都只是读取/检查 http.Request,那仍然可能有问题。是的,多个 goroutine 可以在不同步的情况下读取同一个变量(如果没有人修改它)。但是调用 http.Request 的某些方法也会修改 http.Request,如果没有同步,就不能保证其他 goroutines 会从这个变化中看到什么。例如Request.FormValue()返回与给定键关联的表单值。但是这个方法调用了ParseMultiPartForm()ParseForm()如有必要,修改 http.Request(例如,他们设置 Request.PostFormRequest.Form 结构字段)。

所以除非你同步你的goroutines,否则你不应该将RequestResponseWriter传递给新的goroutine,而是从Request获取需要的数据在处理程序 goroutine 中,仅传递例如保存所需数据的 struct

你的第二个例子:

foo := int64(0)
bar := func() {
// do slow things with foo
}
go bar()

这很好。这是 closure , 并且它所引用的局部变量只要可访问就会继续存在。

请注意,您也可以将局部变量的值作为参数传递给匿名函数调用,如下所示:

foo := int64(0)
bar := func(foo int64) {
// do slow things with param foo (not the local foo var)
}
go bar(foo)

在此示例中,匿名函数将看到并使用其参数 foo 而不是局部变量 foo。这可能是也可能不是你想要的(取决于处理程序是否也使用 foo 以及任何 goroutine 所做的更改是否需要对另一个可见 - 但这无论如何都需要同步,它将被 channel 解决方案取代)。

关于http - Webhook 进程在另一个 goroutine 上运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37782073/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com