如何向goroutine发出信号停止运行?

Ant*_*unt 7 go

我试图阻止一个例行公事,但我找不到实现这个目标的方法.我正在考虑使用第二个频道,但是如果我从中读取它会阻止它不是吗?这是一些代码,我希望解释我正在尝试做什么.

package main

import "fmt"
import "time"

func main() {

    var tooLate bool

    proCh := make(chan string)

    go func() {
        for {
               fmt.Println("working")
        //if is tooLate we stop/return it
            if tooLate { 
            fmt.Println("stopped")
                return
            }
       //processing some data and send the result on proCh
            time.Sleep(2 * time.Second)
            proCh <- "processed"
            fmt.Println("done here")

        }
    }()
    select {
    case proc := <-proCh:
        fmt.Println(proc)
    case <-time.After(1 * time.Second):
        // somehow send tooLate <- true
        //so that we can stop the go routine running
        fmt.Println("too late")
    }

    time.Sleep(4 * time.Second)
    fmt.Println("finish\n")
}
Run Code Online (Sandbox Code Playgroud)

玩这个东西

One*_*One 2

有几种方法可以实现这一点,最简单、最方便的是使用另一个渠道,例如:

func main() {
    tooLate := make(chan struct{})
    proCh := make(chan string)

    go func() {
        for {
            fmt.Println("working")
            time.Sleep(1 * time.Second)
            select {
            case <-tooLate:
                fmt.Println("stopped")
                return
            case proCh <- "processed": //this why it won't block the goroutine if the timer expirerd.
            default: // adding default will make it not block
            }
            fmt.Println("done here")

        }
    }()
    select {
    case proc := <-proCh:
        fmt.Println(proc)
    case <-time.After(1 * time.Second):
        fmt.Println("too late")
        close(tooLate)
    }

    time.Sleep(4 * time.Second)
    fmt.Println("finish\n")
}
Run Code Online (Sandbox Code Playgroud)

playground

您还可以考虑使用sync.Cond