【问题标题】:Cancel go func()取消 go func()
【发布时间】:2018-03-21 08:03:17
【问题描述】:

假设我有一个 golang 函数,类似于:

conn, _ := ln.Accept()
r := bufio.NewReader(conn)

func waiter(r *bufio.Reader) {
    r.ReadString('\n')
}

go waiter(r)
time.Sleep(time.Second)
fmt.Println("hello")

有没有办法让我取消服务员,这样它就不会挂起等待字符串输入,如果它永远不会出现?问题是 bufio 阅读器被阻塞了,我想让它在股票代码上等待两秒钟,如果它没有将任何数据读入缓冲区以逃避 goroutine。

【问题讨论】:

  • 一般情况下你不能取消一个 goroutine,但是在这里你可以简单地关闭连接来中断 Read 调用。你能举一个你实际试图解决的问题的例子吗?
  • 你总是可以设置一个定时器向上调用,并在处理程序中发送一个 EOF 信号。
  • 如果你只想等待一定的时间,你应该在连接上设置一个读取期限。
  • 也许这对你有帮助:rakyll.org/leakingctx

标签: go


【解决方案1】:

Conn 接口提供了一个方法SetReadDeadline 来在特定时间中断过时的操作:

for {
    // Set a deadline for reading. Read operation will fail if no data
    // is received after deadline.
    conn.SetReadDeadline(time.Now().Add(timeoutDuration))

    // Read tokens delimited by newline
    bytes, err := bufReader.ReadBytes('\n')
    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Printf("%s", bytes)
}

http://www.mrleong.net/post/130329994134/go-tcp-connection-listening-and-timeout

【讨论】:

    【解决方案2】:

    编辑:上下文不能对阻塞读取功能做任何事情,也就是说,这不是问题的正确解决方案。在这种情况下,最好为连接设置空闲超时。

    您可以使用context 包来控制goroutines。上下文主要用于在 goroutine 被取消、超时等情况下停止它。要使用它,您必须再接收一个参数 ctx context,并在您的 goroutine 中运行 select。

    来自 Godoc 的示例:

    package main
    
    import (
    "context"
    "fmt"
    "time"
    )
    
    func main() {
    // Pass a context with a timeout to tell a blocking function that it
    // should abandon its work after the timeout elapses.
    ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond)
    defer cancel()
    
    select {
    case <-time.After(1 * time.Second):
        fmt.Println("overslept")
    case <-ctx.Done():
        fmt.Println(ctx.Err()) // prints "context deadline exceeded"
    }
    
    }
    

    在官方博客文章中阅读有关上下文用例的更多信息: https://blog.golang.org/context

    【讨论】:

    • 虽然上下文很有用,但这与取消阻塞读取调用没有任何关系。
    猜你喜欢
    • 2022-01-09
    • 2018-06-30
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 2011-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多