是否可以从http Handle函数写入通道?

时间:2019-03-10 13:47:26

标签: http go channel

我想在发生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上,为什么会这样,又如何实现我想要的?

2 个答案:

答案 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),一切正常!