我想在发生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!")
}
当我向“ /”请求时,它冻结在通道1 <-1上,为什么会这样,又如何实现我想要的?
答案 0 :(得分:1)
是的,有可能。要考虑的一件事是您在通道上发送的数据的生命周期。当前,该通道未缓冲,因此发送:
channel1 <- 1
需要接收:
case <-channel1:
这意味着写入将排队并阻塞,直到准备好进行处理为止。这样做的问题是,一旦接收发生,HTTP处理程序将完成,并且200会向客户端提示该操作已成功OK
。问题是带有接收的另一个go例程可能不完整,因为它与处理程序goroutine同时执行。数据的所有权已转移到另一个goroutine。那么,如果其他goroutine错误却客户端认为该操作已成功完成,该怎么办?
如果通道被缓冲(http处理程序goroutine立即发送然后返回)的缓冲通道将变得更加明显。有很多解决此问题的方法,但是如果不解决,可能会导致数据丢失和逻辑错误。
答案 1 :(得分:0)
知道了,错误在于频道初始化,我不应该写channel1:=make(chan int)
,而是使用channel1=make(chan int)
,一切正常!