Блокируется ли отправка goroutine?

# #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")
}