我想在发生http请求时将值传递给通道,我得到了这段代码:
package main
import (
"io"
"net/http"
"time"
)
var channel1 chan int
func main() {
channel1 := make(chan int)
go func() {
select {
case <-channel1:
fmt.Println("Channel1")
case <-time.After(time.Second * 100):
fmt.Println("Timeout")
}
}()
http.HandleFunc("/", handleMain)
http.ListenAndServe("localhost:8080", nil)
}
func handleMain(w http.ResponseWriter, r *http.Request) {
channel1 <- 1
io.WriteString(w, "Hello from a HandleFunc!")
}
当我向“/”发出请求时,这会冻结在channel1 <-1,为什么会这样,我怎样才能实现我想要的?
对的,这是可能的。需要考虑的一件事是您在频道上发送的数据的生命周期。目前通道是无缓冲的,因此发送:
channel1 <- 1
需要接收:
case <-channel1:
这意味着写入将排队并阻塞,直到它们准备好被处理。这样做的问题是,一旦接收发生,HTTP处理程序就会完成,其中200向客户端建议该操作是OK
并且成功。问题是接收的另一个例程可能不完整,因为它同时执行到处理程序goroutine。数据的所有权已转移到另一个goroutine。那么如果其他goroutine错误但客户认为操作已成功完成会发生什么?
如果通道被缓冲,这将变得更加明显,其中http处理程序goroutine立即发送然后返回。这个问题有很多种解决方案,但如果不加以解决,可能会导致细微的数据丢失和逻辑错误。
知道了,错误是在通道初始化,我不应该写channel1:=make(chan int)
,而是使用channel1=make(chan int)
,一切正常!