|
@@ -0,0 +1,166 @@
|
|
|
|
|
+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)
|
|
|
|
|
+ }
|
|
|
|
|
+}
|