简体   繁体   English

取消go func()

[英]Cancel go func()

Let's say I have a golang function that goes something like: 假设我有一个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")

Is there a way for me to cancel the waiter so it's not hung waiting for a string input if it never comes? 我有什么办法可以取消服务员,这样它就不会挂在等待字符串输入(如果它永远不会出现)? The issue is the bufio reader is blocking, and I want to have it wait for two seconds on a ticker, and if it doesn't read in any data to the buffer to escape the goroutine. 问题是bufio读取器正在阻塞,我想让它在置顶器上等待两秒钟,如果它没有将任何数据读入缓冲区以逃脱goroutine。

Conn interface provides a method SetReadDeadline to interrupt staled operation at specific time: Conn接口提供了一种SetReadDeadline方法来在特定时间中断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 http://www.mrleong.net/post/130329994134/go-tcp-connection-listening-and-timeout

EDIT: Context can't do anything with blocking Read function, that is this is not the correct solution for the question. 编辑:上下文不能执行任何阻止读取功能的操作,这不是该问题的正确解决方案。 Better to set idle timeout to the connection in this situation. 在这种情况下,最好为连接设置空闲超时。

You can use context package to control goroutines. 您可以使用context包来控制goroutine。 Context is mostly used to stop the goroutine in case it is cancelled, timeout, etc. To use it, you must receive one more argument ctx context , and run select in your goroutine. 上下文主要用于停止goroutine,以防它被取消,超时等。要使用它,您必须再接收一个参数ctx context ,并在goroutine中运行select。

Example from Godoc: 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"
}

}

Read more about context use cases in official blog post: https://blog.golang.org/context 在官方博客文章中了解有关上下文用例的更多信息: https : //blog.golang.org/context

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM