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

问题描述 投票:-2回答:2

我想在发生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,为什么会这样,我怎样才能实现我想要的?

http go channel
2个回答
1
投票

对的,这是可能的。需要考虑的一件事是您在频道上发送的数据的生命周期。目前通道是无缓冲的,因此发送:

channel1 <- 1

需要接收:

case <-channel1:

这意味着写入将排队并阻塞,直到它们准备好被处理。这样做的问题是,一旦接收发生,HTTP处理程序就会完成,其中200向客户端建议该操作是OK并且成功。问题是接收的另一个例程可能不完整,因为它同时执行到处理程序goroutine。数据的所有权已转移到另一个goroutine。那么如果其他goroutine错误但客户认为操作已成功完成会发生什么?

如果通道被缓冲,这将变得更加明显,其中http处理程序goroutine立即发送然后返回。这个问题有很多种解决方案,但如果不加以解决,可能会导致细微的数据丢失和逻辑错误。


0
投票

知道了,错误是在通道初始化,我不应该写channel1:=make(chan int),而是使用channel1=make(chan int),一切正常!

© www.soinside.com 2019 - 2024. All rights reserved.