goroutine实现题整理

1、Golang使用2个goroutine分别打印奇偶数,顺序输出1-10

package main

import (
   "fmt"
   "sync"
   "time"
)

var wg sync.WaitGroup
func main() {
   ch := make(chan struct{})
   wg.Add(2)
   go printOdd(ch)
   go printEven(ch)
   wg.Wait()
}

func printOdd(ch chan struct{}) {
   defer wg.Done()
   for i:=1;i<=9;i+=2 {
      time.Sleep(time.Second)
      fmt.Println(i)
      ch <- struct{}{}
   }
}

func printEven(ch chan struct{}) {
   defer wg.Done()
   for i:=2;i<=10;i+=2  {
      <-ch
      time.Sleep(time.Second)
      fmt.Println(i)
   }
}

2、对goroutine实现每秒并发请求数限制

简单的实现,实际应用中可以采用令牌桶限流

package main

import (
   "fmt"
   "time"
)

func main() {
   if err:=recover();err!=nil {
      fmt.Println(err)
   }

   tick1 := time.NewTicker(time.Second)
   ch := make(chan struct{},3)
   for {
      select {
      case <-tick1.C:
         for i:=0;i<=100000;i++ {
            ch<- struct{}{}
            go func() {
               if err:=recover();err!=nil {
                  fmt.Println(err)
               }
               fmt.Println("xxx")
               time.Sleep(time.Second)
               <-ch
            }()
         }
      }
   }
}

3、Go实现两个goroutine交替打印切片并实现超时控制

func PrintArray(list []int, timeout float64) {
   ctx, cancel := context.WithTimeout(context.Background(), time.Second*time.Duration(timeout))
   defer cancel()

   allow := make(chan bool)
   finish := make(chan struct{})

   go func() {
      for i := 0; i < len(list); i++ {
         allow <- true
         time.Sleep(time.Second)
         if i%2 == 0 {
            fmt.Println("goroutine-1:", list[i])
         }
      }

      finish <- struct{}{}
   }()

   go func() {
      for i := 0; i < len(list); i++ {
         <-allow
         if i%2 == 1 {
            fmt.Println("goroutine-2:", list[i])
         }
      }

      finish <- struct{}{}
   }()

   finishCount := 0
   for {
      select {
      case <-ctx.Done():
         fmt.Println("timeout")
         return
      case <-finish:
         finishCount += 1
         if finishCount == 2 {
            return
         }
      }
   }
}

4、实现多个协程按顺序打印数字

func main() {
   a := 0
   fn := func() int {
      a++
      return a
   }
   ch := make(chan int, 1)
   finish := make(chan int, 3)
   for i := 0; i < 3; i++ {
      go func(j int) {
         for {
            ch <- 1
            n := fn()
            if n > 100 {
               finish <- 1
               <-ch
               return
            }
            fmt.Println("go", j, n)
            <-ch
         }

      }(i)
   }

   for i := 0; i < 3; i++ {
      <-finish
   }
}

5、实现每秒打印一次,并且程序不会中断

//题目:原题这样
func main() {
     go func(){
           //在这里写实现的代码
     }()
     
     select{}
 }

func proc() {
    panic("this is a error")
}

//实现:实现这样
func main() {
    go func() {
        ticker := time.NewTicker(time.Second)
        for {
            select {
            case <-ticker.C:
                go func() {
                    defer func() {
                        if err := recover(); err != nil {
                            fmt.Println(err)
                        }
                    }()
                    proc()
                }()
            }
        }
    }()
    select {}
}

func proc() {
    panic("this is a error")
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。