2014-09-30 122 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