package main import ( "fmt" "runtime" "time" ) /* 1. Буферизированный канал. c := make(chan int, 5) Операция чтения такого канала является жадной, т.к. горутина чтения не будет блокироваться до тех пор пока не будет вычетан весь буфер. При записи в канал действует та же логика. */ func squares(c chan int) { for i := 0; i <= 9; i++ { c <- i * i } close(c) } func main() { // foo1() // capChannel() // runtimeChannel() readAfterClose() /* fmt.Println("main() started") c := make(chan int) go squares(c) // range будет считывать данные из канала пока он не будет закрыт // Если в squares не будет close, то будет deadlock for val := range c { fmt.Println(val) } fmt.Println("main() stopped") */ /* for { val, ok := <-c if ok == false { fmt.Println(val, ok, "<-- loop broke!") break // exit break loop } else { fmt.Println(val, ok) } } */ } func squaresRead(c chan int) { for i := 0; i <= 3; i++ { num := <-c fmt.Println(num * num) } } // Буферизированный канал не будет блоикироваться при записи func foo1() { fmt.Println("main() started") c := make(chan int, 3) go squaresRead(c) c <- 1 c <- 2 c <- 3 c <- 4 // c <- 5 // c <- 6 // c <- 7 // c <- 8 // c <- 9 // c <- 10 // time.Sleep(1 * time.Second) fmt.Println("main() stopped") } // ----------------------------------------------------------------- func sender(c chan int) { c <- 1 c <- 2 c <- 3 c <- 4 // goroutine blocks here close(c) } func capChannel() { c := make(chan int, 3) go sender(c) fmt.Printf("Length and capacity of channel c is %v, %v\n", len(c), cap(c)) // read values from c (blocked here) for val := range c { fmt.Printf("Length of channel c after value '%v' len is %v\n", val, len(c)) } } // ----------------------------------------------------------------- func squaresFour(c chan int) { for i := 0; i < 4; i++ { num := <-c fmt.Println(num * num) } } func runtimeChannel() { fmt.Println("main() started") c := make(chan int, 3) go squaresFour(c) fmt.Println("active goroutines", runtime.NumGoroutine()) c <- 1 c <- 2 c <- 3 c <- 4 // bloks here time.Sleep(1 * time.Second) fmt.Println("active goroutines", runtime.NumGoroutine()) go squaresFour(c) fmt.Println("active goroutines", runtime.NumGoroutine()) c <- 5 c <- 6 c <- 7 c <- 8 // bloks here fmt.Println("active goroutines", runtime.NumGoroutine()) fmt.Println("main() stopped") } // ----------------------------------------------------------------- func readAfterClose() { c := make(chan int, 3) c <- 1 c <- 2 c <- 3 close(c) /* for elem := range c { fmt.Println(elem) } */ // Так тоже не будет deadlock for i := 0; i < 5; i++ { fmt.Println(i, <-c) } }