doumaogui5937 2018-06-25 05:38 采纳率: 100%
浏览 31

将值传递给通道由于某种原因阻塞了线程

I'm using a channel to pass messages from an HTTP handler:

package server

import (
    "bytes"
    "errors"
    "io/ioutil"
    "log"
    "net/http"
)

type Server struct {}

func (s Server) Listen() chan interface{} {
    ch := make(chan interface{})
    http.HandleFunc("/", handle(ch))
    go http.ListenAndServe(":8080", nil)
    return ch
}

func handle(ch chan interface{}) func(http.ResponseWriter, *http.Request) {
    return func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "application/json")
        b, err := ioutil.ReadAll(r.Body)
        defer r.Body.Close()
        if err != nil {
            ch <- errors.New(string(500))
            return
        }
        w.Write([]byte("Hello World"))
        log.Print("about to pass to handler channel")
        ch <- bytes.NewBuffer(b)
        log.Print("passed to handler channel")
    }
} 

When I make a request to the server running on port 8080, the thread blocks on this line:

ch <- bytes.NewBuffer(b)

Why is this happening? If you notice, I'm running the listener in a goroutine. I also figured that HTTP handles happen in a separate thread. If I delete the above line, the thread becomes unblocked and the program works as expected. What am I doing wrong?

To clarify, I want to be able to pass the body of a POST request to a channel. Help.

UPDATE: I'm reading from the channel on the main thread:

listenerChan := n.Listen()
go SendRequest("POST", "http://localhost:8080", []byte("hello"))
for listenedMsg := range listenerChan {
    log.Print("listened message>>>> ", listenedMsg)
}

But the thread still blocks on the same line. For clarification, there is nothing wrong with how im sending the request. If I remove the channel send line above, the thread doesnt block.

  • 写回答

3条回答 默认 最新

  • duanfu6160 2018-06-25 05:51
    关注

    Because the channel is unbuffered, the send operation blocks until there's someone who is ready to receive from them. Making the channel buffered will only defer the blocking, so you always need some reading goroutine.

    Update to your update: the control flow of the program would go like this:

    1. Server starts listening
    2. main sends the request and waits for the response
    3. Server receives the request and tries to write to the channel
    4. main reads from the channel

    4 may happen only after 2, which is blocked by 3 which is blocked because 4 is not happening yet. A classical deadlock.

    评论

报告相同问题?

悬赏问题

  • ¥15 seatunnel 怎么配置Elasticsearch
  • ¥15 PSCAD安装问题 ERROR: Visual Studio 2013, 2015, 2017 or 2019 is not found in the system.
  • ¥15 (标签-MATLAB|关键词-多址)
  • ¥15 关于#MATLAB#的问题,如何解决?(相关搜索:信噪比,系统容量)
  • ¥500 52810做蓝牙接受端
  • ¥15 基于PLC的三轴机械手程序
  • ¥15 多址通信方式的抗噪声性能和系统容量对比
  • ¥15 winform的chart曲线生成时有凸起
  • ¥15 msix packaging tool打包问题
  • ¥15 finalshell节点的搭建代码和那个端口代码教程