2016-08-01 128 views
1

我需要創建一個有兩個按鈕的html頁面,一個會啓動一個goroutine,它有一個無限循環,另一個按鈕需要打破無限循環。從我的閱讀中我瞭解到,一個門廳不能從外面被殺死。無論如何要實現這一點?我的代碼如下:如何停止客戶端的goroutine?

command := c.GetString("command") // from client to determine which button is clicked 
quit := make(chan bool) 
switch command { 
    case "start": // Button to start goroutine 
     go func() { 
      i := 0 
      for { 
       select { 
        case <- quit: 
         return 
        default: 
         fmt.Println("i: ", i) 
         i++ 
         time.Sleep(3000 * time.Millisecond) 
       } 
      } 
     }() 
    case "stop": // Button to stop goroutine 
     quit <- true 
} 
+0

這幾乎是標準的做法,是的,你有任何具體的問題嗎? – LinearZoetrope

+0

是否允許多次按「開始」按鈕,即可能有多個goroutine正在運行? – ain

+0

@ain不會有多個門廳... –

回答

1

您對設計已經是對的。一個問題是,您每次收到命令時都會創建新頻道。這意味着沒有辦法與之前開始的goroutine進行交流。您需要有一個quit頻道保持在請求之間的範圍內。嘗試類似下面(未經測試):

func listenForCommand() { 
    var quit chan bool 

    for { 
     // command receiver, should fire for each command received 
     command := c.GetString("command") 

     switch command { 
     case "start": 
      if quit != nil { 
       continue 
      } 
      quit = make(chan bool) 
      go func() { 
       i := 0 
       for { 
        select { 
        case <-quit: 
         return 
        default: 
         fmt.Println("i: ", i) 
         i++ 
         time.Sleep(3000 * time.Millisecond) 
        } 
       } 
      }() 
     case "stop": 
      if quit == nil { 
       continue 
      } 
      quit <- true 
      close(quit) 
      quit = nil 
     } 
    } 
} 

現在,您可以撥打listenForCommand()開始監聽命令。此示例假定存在另一個進程c,因此c.GetString("command")會返回一個命令(如果可用),或阻止並等待命令到達。

+0

你能解釋一下你的命令接收器loop/callback **中定義的註釋嗎?我測試了你的代碼,但停止不工作。可能是我定義的頻道再次錯誤。 –

+0

上面編輯。請注意,它仍然是一個例子。對於上面的例子來說,如上所述,'c.GetString(「command」)'需要像一個通道一樣工作。 – abhink

+0

我們不能從循環中掙脫嗎?我認爲在這段代碼中,開關控制從case「start」轉移到case「stop」,循環仍在運行。 –