如何阻止从UDP读取的goroutine?

时间:2018-03-06 17:26:02

标签: go udp goroutine

我有一个使用goroutine读取UDP数据包的go程序。 我想使用一个select子句和一个“停止”通道来关闭goroutine,以便在不再需要时立即关闭。

以下是goroutine的简单代码示例:

func Run(c chan string, q chan bool, conn *net.UDPConn) {

    defer close(c)

    buf := make([]byte, 1024)

    for {
        select {
            case <- q:
                return
            default:
                n, _, err := conn.ReadFromUDP(buf)
                c <- string(buf[0:n])
                fmt.Println("Received ", string(buf[0:n]))

                if err != nil {
                    fmt.Println("Error: ", err)
                }
        }
    }
}

连接创建为:

    conn, err := net.ListenUDP("udp",addr.Addr)

goroutine应该终止使用:

    close(q)

关闭“停止”通道(“q”)后,goroutine不会立即停止。我需要通过UDP连接再发一个字符串。这样做时,goroutine会停止。 我根本不理解这种行为,如果有人能够启发我,我将不胜感激。

提前谢谢!

1 个答案:

答案 0 :(得分:3)

当您关闭频道时,您的节目可能会在此行停止:

n, _, err := conn.ReadFromUDP(buf)

由于执行是以ReadFrom方法阻止的,因此未评估select语句,因此不会立即检测到通道q上的关闭。当您执行另一个UDP连接发送时,ReadFrom取消阻塞并且(一旦循环迭代完成)控制移动到select语句:此时检测到q上的关闭。 / p>

您可以close the connection取消阻止ReadFrom,如评论中所建议的那样。请参阅PacketConn documentation in the net package,尤其是“任何已阻止的ReadFrom或WriteTo操作都将被取消阻止并返回错误”

// Close closes the connection.
// Any blocked ReadFrom or WriteTo operations will be unblocked and return errors.
Close() error

根据您的需要,也可以选择超时,再次查看PacketConn documentation in the net package

 // ReadFrom reads a packet from the connection,
 // copying the payload into b. It returns the number of
 // bytes copied into b and the return address that
 // was on the packet.
 // ReadFrom can be made to time out and return
 // an Error with Timeout() == true after a fixed time limit;
 // see SetDeadline and SetReadDeadline.
 ReadFrom(b []byte) (n int, addr Addr, err error)