# #go
Вопрос:
Я создал пример здесь: https://play.golang.org/p/kpV3T1XF9bz
По сути, у меня есть основная гороутина, которая создает три дополнительных гороутины. В основной подпрограмме у меня есть цикл for с select
оператором, который выводит результаты созданного канала, за которым следует режим сна.
Когда я запускаю программу, я не вижу задержки ни в одном из моих заявлений о печати. Означает ли это, что отправка goroutines никогда не блокируется?
Я ожидал, что, пока основная подпрограмма спала, прежде чем мы вернемся к select
заявлению, небуферизованный канал не будет готов принять новые данные, но то, что я вижу, противоречит этому.
ПРАВКА: Обновлена ссылка на игровую площадку с надлежащей задержкой в секундах.
Комментарии:
1. Операции отправки блокируются, когда они заблокированы, и вы блокируете их, но только на очень короткое время.
5 % time.Second
==5ns
, я полагаю, вы имели в виду5 * time.Second
.2. Кстати, нет никаких причин для
select
того, чтобы с помощью одногоcase
и зацикливания по одному каналу можно было выполнитьfor output := range c {
3. Что ж, я буду, спасибо за улов. Похоже, все работает так, как ожидалось. Вот обновленная ссылка: play.golang.org/p/kpV3T1XF9bz . Похоже, отправитель заблокирован? Порядок вывода, по — видимому, находится в случайном порядке.
4. Да, они заблокированы, потому что именно так устроены каналы для работы-они обеспечивают синхронизацию отправителя и получателя. Порядок вывода является случайным, потому что гороутины параллельны и код не налагает никакого порядка.
5. Да, отправляющая горутина блокируется до тех пор, пока основная горутина не будет готова к приему. Я не вижу в выводе ничего, что противоречило бы этому. Вопросы должны включать соответствующий встроенный код.
Ответ №1:
Вам не нужно использовать select
. Просто используйте for loop
, это решит вашу проблему. Вот код.
package main
import (
"fmt"
"time"
)
func First(c chan string) {
c <- "FirstOne"
// fmt.Println("First string")
}
func Second(c chan string) {
c <- "SecondOne"
// fmt.Println("Second string")
}
func Third(c chan string) {
c <- "ThirdOne"
// fmt.Println("Third string")
}
func main() {
c := make(chan string)
go First(c)
go Second(c)
go Third(c)
for i := 0; i < 3; i {
fmt.Println(<-c)
time.Sleep(time.Second * 2)
}
fmt.Println("Timeout")
}