【问题标题】:How can I stop a goroutine that is reading from UDP?如何停止从 UDP 读取的 goroutine?
【发布时间】:2018-08-14 15:43:40
【问题描述】:

我有一个使用 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 停止。 我根本不理解这种行为,如果有人能启发我,我将不胜感激。

提前谢谢你!

【问题讨论】:

  • 你尝试关闭连接了吗?
  • 建议关闭您打开它们的频道。 defer 声明是为了促进这种行为(同时打开和关闭,这样你就不会忘记关闭)。这也可能是您观察到的行为的影响因素
  • @NorbertvanNobelen:不,关闭通道不是清理操作,您不需要关闭它们,关闭它们通常是不正确的。
  • @JimB 我的评论是关于在同一位置打开和关闭,而不是在两个不同的功能中。由于延迟关闭不是在创建通道时,因此呈现的代码可能会令人困惑。

标签: go udp goroutine


【解决方案1】:

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

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

因为在 ReadFrom 方法处执行被阻止,select 语句未被评估,因此不会立即检测到通道 q 上的关闭。当您在 UDP 连接上进行另一次发送时,ReadFrom 会解除阻塞,并且(一旦循环迭代完成)控制将移至 select 语句:此时检测到 q 上的关闭。

您可以按照评论中的建议,通过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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-12
    • 2017-07-19
    • 2018-04-24
    • 1970-01-01
    • 2018-02-19
    • 2017-08-23
    • 1970-01-01
    • 2013-02-13
    相关资源
    最近更新 更多