2014-09-30 124 views
8

我试图阻止一个去程序,但我找不到一种方法来实现这一点。我正在考虑使用第二频道,但如果我从中读到它会阻止它,不是吗?这里有一些代码,我希望解释我想要做的事情。如何通知goroutine停止运行?

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") 
} 

Play this thing

+0

http:// s的可能重复tackoverflow.com/questions/6807590/how-to-stop-a-goroutine – jimt 2014-09-30 14:01:34

回答

3

有多种方法才达到的是,最简单,用另一声道最喜欢的方便:

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") 
} 

playground

您也可以考虑使用sync.Cond

+0

为什么我们需要''案例proCh < - “处理过的”:''从第一个例程中选择第二个案例?如果计时器由于“tooLate < - true”而过期,它会返回,所以不可能有这种情况不是吗? – 2014-09-30 14:00:51

+0

@AnthonyHat否,因为在case <-time.After(1 * time.Second)之后''你的goroutine会卡住试图处理''proCh < - “processed”,并且在程序退出之前它不会解除阻塞。 – OneOfOne 2014-09-30 14:55:09

+0

@OneOfOne如果计时器到期够程只需返回''情况下<-tooLate: \t \t \t \t fmt.Println( “停止”) \t \t \t \t return''它似乎并没有阻止,我也做看到任何理由。 http://play.golang.org/p/MvmjBXfAqV – 2014-10-01 06:13:45