2 回答
![?](http://img1.sycdn.imooc.com/5458689e000115c602200220-100-100.jpg)
TA贡献1816条经验 获得超6个赞
为每个 http 请求提供服务在其自己的 goroutine 中运行(更多详细信息)。您可以从您的处理程序启动新的 goroutine,它们将同时运行,独立于执行处理程序的 goroutine。
需要注意的一些事项:
新的 goroutine 独立于处理程序 goroutine 运行。这意味着它可能在处理程序 goroutine 之前或之后完成,如果没有显式同步,您不能(不应该)假设与此有关的任何事情。
处理程序的http.ResponseWriter和http.Request参数仅在处理程序返回之前有效且安全使用!这些值(或它们的“部分”)可以重复使用 - 这是一个实现细节,您也不应该对其进行任何假设。一旦处理程序返回,您不应该触摸(甚至不读取)这些值。
一旦处理程序返回,响应就会被提交(或者可能随时提交)。这意味着您的新 goroutine 不应尝试使用http.ResponseWriterafter this 发回任何数据。这在某种程度上是正确的,即使您不触摸http.ResponseWriter处理程序中的 ,处理程序的不恐慌也被视为成功处理请求,因此返回 HTTP 200 状态(参见示例)。
您可以将http.Requestandhttp.ResponseWriter值传递给其他函数和新的 goroutine,但必须注意:如果您打算从多个 goroutine 读取/修改这些值(或者您想要从多个 goroutine 发回数据)。
请注意,如果您的处理程序 goroutine 和新的 goroutine 都只是读取/检查http.Request,这似乎仍然可能是有问题的。是的,多个 goroutine 可以在不同步的情况下读取同一个变量(如果没有人修改它)。但是调用 的某些方法http.Request也会修改http.Request,如果没有同步,就不能保证其他 goroutine 会从这个变化中看到什么。例如Request.FormValue(),返回与给定键关联的表单值。但是这个方法调用ParseMultiPartForm()并ParseForm()在必要时对其进行修改http.Request(例如,他们设置了Request.PostForm和Request.Form结构字段)。
因此,除非您同步您的 goroutine,否则您不应将Requestand传递ResponseWriter给新的 goroutine,而是从Request处理程序 goroutine 中获取所需的数据,并仅传递例如struct保存所需数据的 a。
你的第二个例子:
foo := int64(0)
bar := func() {
// do slow things with foo
}
go bar()
这很好。这是一个闭包,它所引用的局部变量只要可访问,就会继续存在。
请注意,您也可以将局部变量的值作为参数传递给匿名函数调用,如下所示:
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 所做的更改对另一个可见 - 但这无论如何都需要同步,这将被通道解决方案取代)。
![?](http://img1.sycdn.imooc.com/54584ee0000179f302200220-100-100.jpg)
TA贡献1906条经验 获得超10个赞
如果您关心邮件的确认,那么发布的代码将无济于事。在单独的 goroutine 中运行代码使其独立,即使由于 goroutine 函数中的某些错误导致邮件未发送,服务器也会回复成功。
- 2 回答
- 0 关注
- 113 浏览
添加回答
举报