channel_anatomy.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. package main
  2. import (
  3. "fmt"
  4. "runtime"
  5. "time"
  6. )
  7. /*
  8. 1. Буферизированный канал.
  9. c := make(chan int, 5)
  10. Операция чтения такого канала является жадной, т.к. горутина чтения не будет
  11. блокироваться до тех пор пока не будет вычетан весь буфер.
  12. При записи в канал действует та же логика.
  13. */
  14. func squares(c chan int) {
  15. for i := 0; i <= 9; i++ {
  16. c <- i * i
  17. }
  18. close(c)
  19. }
  20. func main() {
  21. // foo1()
  22. // capChannel()
  23. // runtimeChannel()
  24. readAfterClose()
  25. /*
  26. fmt.Println("main() started")
  27. c := make(chan int)
  28. go squares(c)
  29. // range будет считывать данные из канала пока он не будет закрыт
  30. // Если в squares не будет close, то будет deadlock
  31. for val := range c {
  32. fmt.Println(val)
  33. }
  34. fmt.Println("main() stopped")
  35. */
  36. /*
  37. for {
  38. val, ok := <-c
  39. if ok == false {
  40. fmt.Println(val, ok, "<-- loop broke!")
  41. break // exit break loop
  42. } else {
  43. fmt.Println(val, ok)
  44. }
  45. }
  46. */
  47. }
  48. func squaresRead(c chan int) {
  49. for i := 0; i <= 3; i++ {
  50. num := <-c
  51. fmt.Println(num * num)
  52. }
  53. }
  54. // Буферизированный канал не будет блоикироваться при записи
  55. func foo1() {
  56. fmt.Println("main() started")
  57. c := make(chan int, 3)
  58. go squaresRead(c)
  59. c <- 1
  60. c <- 2
  61. c <- 3
  62. c <- 4
  63. // c <- 5
  64. // c <- 6
  65. // c <- 7
  66. // c <- 8
  67. // c <- 9
  68. // c <- 10
  69. // time.Sleep(1 * time.Second)
  70. fmt.Println("main() stopped")
  71. }
  72. // -----------------------------------------------------------------
  73. func sender(c chan int) {
  74. c <- 1
  75. c <- 2
  76. c <- 3
  77. c <- 4 // goroutine blocks here
  78. close(c)
  79. }
  80. func capChannel() {
  81. c := make(chan int, 3)
  82. go sender(c)
  83. fmt.Printf("Length and capacity of channel c is %v, %v\n", len(c), cap(c))
  84. // read values from c (blocked here)
  85. for val := range c {
  86. fmt.Printf("Length of channel c after value '%v' len is %v\n", val, len(c))
  87. }
  88. }
  89. // -----------------------------------------------------------------
  90. func squaresFour(c chan int) {
  91. for i := 0; i < 4; i++ {
  92. num := <-c
  93. fmt.Println(num * num)
  94. }
  95. }
  96. func runtimeChannel() {
  97. fmt.Println("main() started")
  98. c := make(chan int, 3)
  99. go squaresFour(c)
  100. fmt.Println("active goroutines", runtime.NumGoroutine())
  101. c <- 1
  102. c <- 2
  103. c <- 3
  104. c <- 4 // bloks here
  105. time.Sleep(1 * time.Second)
  106. fmt.Println("active goroutines", runtime.NumGoroutine())
  107. go squaresFour(c)
  108. fmt.Println("active goroutines", runtime.NumGoroutine())
  109. c <- 5
  110. c <- 6
  111. c <- 7
  112. c <- 8 // bloks here
  113. fmt.Println("active goroutines", runtime.NumGoroutine())
  114. fmt.Println("main() stopped")
  115. }
  116. // -----------------------------------------------------------------
  117. func readAfterClose() {
  118. c := make(chan int, 3)
  119. c <- 1
  120. c <- 2
  121. c <- 3
  122. close(c)
  123. /*
  124. for elem := range c {
  125. fmt.Println(elem)
  126. }
  127. */
  128. // Так тоже не будет deadlock
  129. for i := 0; i < 5; i++ {
  130. fmt.Println(i, <-c)
  131. }
  132. }