登录
首页 >  Golang >  Go问答

处理Go中阻塞操作的方法

来源:stackoverflow

时间:2024-02-23 18:12:24 288浏览 收藏

今日不肯埋头,明日何以抬头!每日一句努力自己的话哈哈~哈喽,今天我将给大家带来一篇《处理Go中阻塞操作的方法》,主要内容是讲解等等,感兴趣的朋友可以收藏或者有更好的建议在评论提出,我都会认真看的!大家一起进步,一起学习!

问题内容

我正在使用 golang,想要编写一个应用程序来启动一个提供某些内容的 http 服务器,并且内容是通过消息队列从另一个应用程序更新的。

我面临的问题是监听队列和启动服务器,这两件事似乎都会阻塞,我不太确定我当前的解决方案是否正确。

如果我这样写,那么服务器永远不会启动

forever := make(chan bool)
    go func() {
        for d := range msgs {
            log.printf("received a message: %s", d.body)
        }
    }()
    <-forever

    http.listenandserve(fmt.sprintf(":%d", port), t.handler)

如果我这样写,那么应用程序将永远不会开始监听队列

http.listenandserve(fmt.sprintf(":%d", port), t.handler)

    forever := make(chan bool)
    go func() {
        for d := range msgs {
            log.printf("received a message: %s", d.body)
        }
    }()
    <-forever

所以我当前的解决方案是将 listenandserver 放在永久块中,这似乎可行,但我不确定这是否是正确的方法

    forever := make(chan bool)
    go func() {
        for d := range msgs {
            log.Printf("Received a message: %s", d.Body)
        }
    }()
    http.ListenAndServe(fmt.Sprintf(":%d", port), t.handler)
    <-forever

正确答案


据我所知, <-forever 会造成死锁,因为不会在其上放置任何内容。 http.listenandserve 是阻塞的(将其视为启动事件循环),因此如果您想运行它而不阻塞主 goroutine(不推荐),您可以从另一个 goroutine 调用它。

<-forever 行会阻止所有内容,因为它不会接收任何内容。

如果您希望通道无阻塞,则必须使用缓冲通道。但您必须确保正确阅读。

// replace interface{} with your own type

func readContent (msg <-chan interface{}, toHandler chan<- interface{} , ...args){
      // your handler func
      for d := range msg{
          toHandler <- d
      }       
      // rest of function
}

// with closure. you can do it with struct properties also
func messageHandler(msg <-chan interfcae{}) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
         message := make ([]interface{},0)
         for d := range msg {
            message = append (message, d)
         }
         // send it to  the client
         w.Write([]byte(message)
    })
}



// inside main routine
// 
// do your own work without <-forever
// Listen and serve will open a new Goroutine for each client request
http.ListenAndServe(fmt.Sprintf(":%d", port), t.handler)

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>