2016-08-01 7 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

Разрешено несколько раз нажимать кнопку «старт», т. Е. Может быть более одного горутина? – ain

+0

@ain Нет, не будет нескольких goroutines ... –

ответ

1

Вы уже имеете право на дизайн. Проблема в том, что вы создаете новые каналы каждый раз, когда получаете команду. Это означает, что нет способа связаться с ранее запущенным горутином. Вы должны иметь канал 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

Разве мы не можем выйти из цикла? Я думаю, что в этом коде управление переключателем передается на случай «stop» из «start» из цикла, цикл все еще работает. –