Как мне узнать, выполнена ли подпрограмма без блокировки?

StackOverflow https://stackoverflow.com/questions/1730719

  •  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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top