【问题标题】:Is it possible to write to a channel from http Handle function?是否可以从 http Handle 函数写入通道?
【发布时间】:2019-07-31 23:14:25
【问题描述】:

我想在发生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

【问题讨论】:

  • 当然。您可以从任何函数写入通道。为什么你会认为这是不同的?

标签: http go channel


【解决方案1】:

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

【讨论】:

  • 影子变量。 “去兽医”可以帮助你抓住这些。见here
【解决方案2】:

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

channel1 &lt;- 1

需要接收:

case &lt;-channel1:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-15
    • 2020-09-26
    相关资源
    最近更新 更多