func close(c chan<- Type)
内建函数close关闭信道,该通道必须为双向的或只发送的。它应当只由发送者执行,而不应由接收者执行,其效果是在最后发送的值被接收后停止该通道。在最后的值从已关闭的信道中被接收后,任何对其的接收操作都会无阻塞的成功。对于已关闭的信道,语句:
x, ok := <-c
还会将ok置为false。

需求

请完成goroutine和channel协同工作的案例,具体要求:
1)开启一个writeData协程,向管道intChan中写入50个整数.
2)开启一个readData协程,从管道intChan中读取writeData写入的数据。
3) 注意:writeData和readDate操作的是同一个管道
4) 主线程需要等待writeData和readDate协程都完成工作才能退出

思路分析

image.png

代码

  1. // goroutine + channel 案例
  2. package main
  3. import (
  4. "fmt"
  5. )
  6. // write data
  7. func writeData(intChan chan int) {
  8. for i := 1; i <= 50; i++ {
  9. intChan <- i
  10. fmt.Printf("写入数据: %v \n", i)
  11. }
  12. close(intChan)
  13. }
  14. // read data
  15. func readData(intChan chan int, exitChan chan bool) {
  16. for {
  17. v, ok := <-intChan
  18. if !ok {
  19. break
  20. } else {
  21. fmt.Printf("读到数据了: %v \n", v)
  22. }
  23. }
  24. exitChan <- true
  25. close(exitChan)
  26. }
  27. func main() {
  28. // 创建两个管道
  29. intChan := make(chan int, 50)
  30. exitChan := make(chan bool, 1)
  31. go writeData(intChan)
  32. go readData(intChan, exitChan)
  33. // time.Sleep(time.Second * 10)
  34. // 阻塞的方式
  35. for {
  36. v, ok := <-exitChan
  37. if !ok {
  38. break
  39. } else {
  40. fmt.Printf("结束了: %v \n", v)
  41. }
  42. }
  43. fmt.Println("over~")
  44. }

阻塞机制

读和写不同步也不会报错,但是写入之后必须读取,否则会 deadlock
不受读写快慢的影响
写入之后不读取,会造成阻塞,channel里的数据永远不会释放,协程就永远被占用,deadlock(不知道是不是这样-_-)

作业一

image.png

作业二

image.png