Как мне узнать, выполнена ли подпрограмма без блокировки?
-
20-09-2019 - |
Вопрос
Все примеры, которые я видел до сих пор, включают блокировку для получения результата (через <-chan
оператор).
Мой текущий подход включает в себя передачу указателя на структуру:
type goresult struct {
result resultType;
finished bool;
}
который программа goroutine записывает по завершении.Тогда это простой вопрос проверки finished
когда это удобно.Есть ли у вас лучшие альтернативы?
К чему я действительно стремлюсь, так это к системе сигнальных слотов в стиле Qt.У меня есть предчувствие, что решение будет выглядеть почти тривиально (chan
у них есть Лоты неизведанного потенциала), но я еще недостаточно знаком с языком, чтобы разобраться в этом.
Решение
Вы можете использовать шаблон "запятая, ок" (смотрите их страницу на "эффективный переход"):
foo := <- ch; // This blocks.
foo, ok := <- ch; // This returns immediately.
Другие советы
Выберите инструкции позволяет вам проверять несколько каналов одновременно, выбирая случайную ветвь (из тех, где связь ожидает).:
func main () {
for {
select {
case w := <- workchan:
go do_work(w)
case <- signalchan:
return
// default works here if no communication is available
default:
// do idle work
}
}
}
Для всех выражений отправки и получения в инструкции "выбрать" вычисляются выражения канала, вместе с любыми выражениями, которые появляются в правой части send выражения в порядке сверху вниз.Если какая-либо из результирующих операций может выполняться, выбирается одна из них и оцениваются соответствующие сообщения и инструкции.В противном случае, если есть вариант по умолчанию, который выполняет;если нет, оператор блокируется до тех пор, пока одно из сообщений не сможет завершиться.
Вы также можете заглянуть в буфер канала, чтобы увидеть, содержит ли он что-нибудь, используя len:
if len(channel) > 0 {
// has data to receive
}
Это не коснется буфера канала, в отличие от foo, gotValue := <- ch
который удаляет значение, когда gotValue == true
.