С do c:
Если канал не буферизован, отправитель блокируется, пока получатель не получит значение. Если у канала есть буфер, отправитель блокируется только до тех пор, пока значение не будет скопировано в буфер; если буфер заполнен, это означает ожидание, пока какой-либо получатель не получит значение.
Один из способов - использовать это. Вот и получатель goroutine создается первым. Кроме того, если приемник еще не готов, будет выбран регистр по умолчанию. И если он будет готов, указанный случай c будет готов. Если вы запустите это несколько раз, вы увидите, что происходит один из следующих случаев.
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int)
// goroutine acts as the reciever
go func() {
fmt.Printf("main at %d\n", time.Now().UnixNano())
fmt.Println(<-ch)
}()
go func() {
fmt.Printf("func at %d\n", time.Now().UnixNano())
select {
case ch <- 1:
fmt.Println("running send")
default:
fmt.Println("running default")
}
}()
time.Sleep(1 * time.Second) // Wait for the goroutines
}
Другое решение будет использовать буферизованный канал:
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int, 1)
go func() {
fmt.Printf("func at %d\n", time.Now().UnixNano())
select {
case ch <- 1:
fmt.Println("running send")
default:
fmt.Println("running default")
}
}()
time.Sleep(100 * time.Millisecond)
fmt.Printf("main at %d\n", time.Now().UnixNano())
fmt.Println(<-ch)
}
Также прочитайте это thread on stackoverflow