Golang非阻塞通道不工作

Golang非阻塞通道不工作,go,websocket,goroutine,Go,Websocket,Goroutine,我第一次在go中使用goroutines和Channel,以后不再使用 我有一个websocket连接,每次用户连接时都会产生一个新的goroutine。现在,如果用户从websocket连接断开连接,我想停止这个goroutine 为了管理停止信号,我创建了通道图。每个条目都可以由用户websocket连接识别。我将websocket连接、停止信号通道图和其他两个参数传递给goroutine。但是goroutine没有从退出频道收到任何值,我也不知道为什么 以下是主程序包的相关代码: 我也尝试

我第一次在go中使用goroutines和Channel,以后不再使用

我有一个websocket连接,每次用户连接时都会产生一个新的goroutine。现在,如果用户从websocket连接断开连接,我想停止这个goroutine

为了管理停止信号,我创建了通道图。每个条目都可以由用户websocket连接识别。我将websocket连接、停止信号通道图和其他两个参数传递给goroutine。但是goroutine没有从退出频道收到任何值,我也不知道为什么

以下是主程序包的相关代码:

我也尝试过缓冲通道,或者将通道而不是通道映射传递给goroutine,但没有成功。永远不会调用fmt.PrintlnQUIT GOROUTINE命令,也不会对GOROUTINE进行SOP


我希望有人能帮助我,如果这个问题已经被问到,我很抱歉,但我还没有找到解决问题的方法。

首先让事情变得更简单:

据我所知,退出频道不需要全局注册。只需在main中创建一个ch:=makechan bool,将其传递给ListenToTable,而不是整个通道图,并在select中使用它。如果您想退出,请在main中关闭它。但正如你所说,这并不能解决你的问题

从理论上讲,结束围棋程序是正确的。我获取了您的示例代码,并从中生成了以下可运行代码:

package main

import (
    "fmt"
    "time"
)

func main() {

    chClose := make(chan bool)
    channel := make(chan string)

    ListenToTable("somestring", channel, chClose)

    time.Sleep(3 * time.Second)
    chClose <- true
    time.Sleep(1 * time.Second)
}

func ListenToTable(name string, ch chan string, chClose chan bool) {
    go func(name string) {
        for {
            select {
            case <-chClose:
                fmt.Println("QUIT GOROUTINE")
                return  // VERY IMPORTANT: not break!
            default:
            }
        }
    }(name)
}
问题一定出在代码中的其他内容上,可能被默认部分中的某些内容阻止,甚至没有执行select。尝试在选择{之前打印fmt.Printlnsomething。如果没有定期打印,那么您就有了答案


还有一件事:正如上面代码中所评论的,您不能中断{select{…}的使用单中断。您需要使用返回退出函数或其他策略,如Adrian在评论中建议的带标签的中断。中断将只退出select循环,而不会退出for循环。

Thx用于回复。您是对的,问题不是停止信号。问题在默认语句中,它是阻塞的。Onl我想我要做的就是将RejectDB的光标传递到goroutine,从goroutine外部关闭它。另请参见:
package data

var Quit = make(map[*websocket.Conn](chan bool))

func (db *rethinkDB) ListenToTable(name string, ch chan Data, quit map[*websocket.Conn](chan bool), ws *websocket.Conn) {
    go func(name string, ws *websocket.Conn) {
        for {
            select {
            case <-quit[ws]:
                fmt.Println("QUIT GOROUTINE")
                break
            default:
                res, err := r.Table(name).Changes().Run(db.session)
                if err != nil {
                    log.Fatalln(err)
                }

                var response DataFeed
                for res.Next(&response) {
                    response.NewVal.WS = ws
                    ch <- response.NewVal
                }

                if res.Err() != nil {
                    log.Println(res.Err())
                }
            }
        }
    }(name, ws)
}
package main

import (
    "fmt"
    "time"
)

func main() {

    chClose := make(chan bool)
    channel := make(chan string)

    ListenToTable("somestring", channel, chClose)

    time.Sleep(3 * time.Second)
    chClose <- true
    time.Sleep(1 * time.Second)
}

func ListenToTable(name string, ch chan string, chClose chan bool) {
    go func(name string) {
        for {
            select {
            case <-chClose:
                fmt.Println("QUIT GOROUTINE")
                return  // VERY IMPORTANT: not break!
            default:
            }
        }
    }(name)
}