我是靠谱客的博主 英俊香菇,最近开发中收集的这篇文章主要介绍Go语言使用channel等待任务结束,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一、使用channel来等待goroutine结束

方法一:

type worker struct {
   in chan int
   done chan bool
}

func doneWorker(id int, w worker) {
   for n := range w.in {
      fmt.Printf("worker %d received %cn", id, n)
      w.done <- true
   }
}

func createWorker(id int) worker{
   w := worker{
      in: make(chan int),
      done: make(chan bool),
   }

   go doneWorker(id, w)
   return w
}

func chanDemo() {
   var workers [10]worker

   for i, _ := range workers {
      workers[i] = createWorker(i)
   }

   for i, worker := range workers {
       worker.in <- 'a' + i
   }

   for _, worker := range workers{
      <- worker.done
   }

   for i, worker := range workers {
      worker.in <- 'A' + i
   }

   for _, worker := range workers{
      <- worker.done
   }
}

func main() {
   chanDemo()
}

方法二:

type worker struct {
   in chan int
   done func()
}

func doneWorker(id int, w worker) {
   for n := range w.in {
      fmt.Printf("worker %d received %cn", id, n)
      w.done()
   }
}

func createWorker(id int, wg *sync.WaitGroup) worker{
   w := worker{
      in: make(chan int),
      done: func() {
         wg.Done()
      },
   }

   go doneWorker(id, w)
   return w
}

func chanDemo() {
   var wg sync.WaitGroup

   var workers [10]worker
   for i, _ := range workers {
      workers[i] = createWorker(i, &wg)
   }

   wg.Add(20)

   for i, worker := range workers {
       worker.in <- 'a' + i
   }

   for i, worker := range workers {
      worker.in <- 'A' + i
   }

   wg.Wait()
}

func main() {
   chanDemo()
}

二、使用Channel来实现树的遍历

func (node *Node) TraverseWithChannel() chan *Node{
   out := make(chan *Node)
   go func() {
      node.TraverseFunc(func(node *Node) {
         out <- node
      })
      close(out)
   }()

   return out
}

三、使用Select来进行调度

1.定时器的使用
2.select中使用Nil channel
3.select default(非阻塞式从channel中获取值)

func generator() chan int{
   out := make(chan int)
   go func() {
      i := 0
      for {
         time.Sleep(time.Duration(rand.Intn(1500)) * time.Millisecond)
         out <- i
         i++
      }
   }()

   return out
}

func worker(id int, c chan int)  {
   for n := range c {
      time.Sleep(1 * time.Second)
      fmt.Printf("Worker %d received %dn", id, n)
   }
}

func createWorker(id int) chan int{
   c := make(chan int)
   go worker(id, c)
   return c
}

func main() {
   var c1, c2 = generator(), generator() // c1 and c2 = nil
   w := createWorker(0)
   var values []int
   tm := time.After(10 * time.Second)
   tick := time.Tick(time.Second)
   for {
      var activeWorker chan int
      var activerValue int
      if len(values) > 0 {
         activeWorker = w
         activerValue = values[0]

      }
      select {
      case n := <-c1:
         values = append(values, n)
      case n := <-c2:
         values = append(values, n)
      case activeWorker <-activerValue:
         values = values[1:]
      case <-time.After(800 * time.Millisecond):
         fmt.Println("timeout")
      case <-tick:
         fmt.Println("queue len =", len(values))
      case <-tm:
         fmt.Println("Bye")
         return

      //default:
         //fmt.Println("No value received")
      }
   }
}

四、传统同步机制

1.WaitGroup
2.Mutex
3.Cond

type atomicInt struct {
   value int
   lock sync.Mutex
}

func (a *atomicInt)  increment(){
   fmt.Println("safe increment")
   func(){
      a.lock.Lock()
      defer a.lock.Unlock()
      a.value++
   }()
}

func (a *atomicInt) get() int {
   a.lock.Lock()
   defer a.lock.Unlock()

   return a.value
}
func main() {
   var a atomicInt
   a.increment()
   go func() {
      a.increment()
   }()
   time.Sleep(time.Millisecond)
   fmt.Println(a.get())
}

最后

以上就是英俊香菇为你收集整理的Go语言使用channel等待任务结束的全部内容,希望文章能够帮你解决Go语言使用channel等待任务结束所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(62)

评论列表共有 0 条评论

立即
投稿
返回
顶部