简体   繁体   中英

Cancel go func()

Let's say I have a golang function that goes something like:

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.

Conn interface provides a method SetReadDeadline to interrupt staled operation at specific time:

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

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 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.

Example from 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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