协程和并发的应用案例

91 阅读1分钟

协程和并发的应用案例

应用案例:

  • 用goroutine和channel协同工作完成
  • 1.开启一个writeData协程,向管道intChan中写入50个整数
  • 2.开启一个readData协程,从管道intChan中读取writeData写入的数据
  • 注意:读写操作是同一个管道的数据,主线程需要等待读写的协程完成才能退出
 package main
 ​
 import "fmt"
 ​
 // 写入
 func write(intChan chan int) {
     for i := 0; i <= 50; i++ {
         intChan <- i
     }
     close(intChan)
 }
 ​
 // 读出
 func read(intChan chan int, doneRead chan bool) {
 ​
     for {
         val, ok := <-intChan
         if !ok {
             break
         }
         fmt.Println("输出:", val)
     }
     doneRead <- true
 }
 ​
 func main() {
     intChan := make(chan int)
     doneRead := make(chan bool)
     //写入50个整数
     go write(intChan)
     //读出数据
     go read(intChan, doneRead)
     //结束进程
     <-doneRead
     close(doneRead)
     fmt.Println("输出结束")
     return
 }
 ​

利用defer 匿名函数捕获panic

  • 演示
 defer func(){
     if err:=recover();err!=nil{
         fmt.Println("此方法有panic:",err)
     }
 }()
  • 应用地方: 应用在你觉得或者觉得会出现panic的地方

定时器定时任务

  • 方法一:timer:=time.NewTimer(定时时间)//定时时间
  • t:= <-time.C//到点就自动发送数据
  • 方法二 : t := <-time.After(定时时间)//定时并到点发送数据
  • 总结: 方法二是方法一的封装,两者内部是一致的

定时器的暂停和重置

  • 暂停: timer.Stop()(必须用方法一定时任务)
  • 重置: timer.Reset(时间)
 package main
 ​
 import (
     "fmt"
     "math/rand"
     "time"
 )
 ​
 var isStop = isStopTimer()
 ​
 func main() {
     fmt.Println(time.Now())
     timer := time.NewTicker(time.Second * 3)
     if isStop {
         fmt.Println(<-timer.C)
     } else {
         timer.Stop()
     }
 }
 ​
 func isStopTimer() bool {
     rand.Seed(time.Now().UnixNano())
     tempInt := rand.Intn(4) + 16
     if tempInt >= 18 {
         fmt.Println("找到了")
         return true
     } else {
         return false
     }
 }
 ​

循环时钟的任务

  • 设置时间格式fmt.Println((<-ticker.C).Format("2006-01-02 03:04:05PM"))

  • 2006-01-02 03:04:05PM不能改变数字,PM是转为24进制

  • 这里利用:

    • time.NewTicker(时间)循环获取时间点
 package main
 ​
 import (
     "fmt"
     "time"
 )
 ​
 func main() {
     ticker := time.NewTicker(time.Second)
     done := make(chan struct{})//
     go func(done chan struct{}) {
         var count = 0
         for {
             fmt.Println((<-ticker.C).Format("2006-01-02 03:04:05PM"))
             count++
             if count > 2 {
                 ticker.Stop()
                 done <- struct{}{}//
             }
         }
     }(done)
     <-done//
     fmt.Println("打印结束")
 }
 ​

利用任务队列等待任务完成

  • 利用的包:waitGroup := sync.WaitGroup{}
  • 三个主要函数:Add(),Done(),Wait()
 package main
 ​
 import (
     "fmt"
     "sync"
     "time"
 )
 ​
 func main() {
     waitGroup := sync.WaitGroup{}
     ticker := time.NewTicker(time.Second)
     waitGroup.Add(1)//
     go func() {
         var count = 0
         for {
             fmt.Println((<-ticker.C).Format("2006-01-02 03:04:05PM"))
             count++
             if count > 2 {
                 waitGroup.Done()//
                 ticker.Stop()
             }
         }
     }()
     waitGroup.Wait()//
     fmt.Println("打印结束")
 }