zoukankan      html  css  js  c++  java
  • 【转】Go by Example: Worker Pools

    原文:https://gobyexample.com/worker-pools

    Our running program shows the 5 jobs being executed by various workers. The program only takes about 2 seconds despite doing about 5 seconds of total work because there are 3 workers operating concurrently.

    package main
    
    import (
        "fmt"
        "time"
    )
    
    func worker(id int, jobs <-chan int, results chan<- int) {
        for j := range jobs {
            fmt.Println("worker", id, "started  job", j)
            time.Sleep(time.Second)
            fmt.Println("worker", id, "finished job", j)
            results <- j * 2
        }
    }
    
    func main() {
    
        const numJobs = 5
        jobs := make(chan int, numJobs)
        results := make(chan int, numJobs)
    
        for w := 1; w <= 3; w++ {
            go worker(w, jobs, results)
        }
    
        for j := 1; j <= numJobs; j++ {
            jobs <- j
        }
        close(jobs)
    
        for a := 1; a <= numJobs; a++ {
            <-results
        }
    }
    

      

    下面这个版本为什么会死锁呢??

     package main
     
     import "fmt"
     import "time"
     
     // Here's the worker, of which we'll run several
     // concurrent instances. These workers will receive
     // work on the `jobs` channel and send the corresponding
     // results on `results`. We'll sleep a second per job to
     // simulate an expensive task.
     func worker(id int, jobs <-chan int, results chan<- int) {
         for j := range jobs {
             fmt.Println("worker", id, "started  job", j)
             time.Sleep(time.Second)
             fmt.Println("worker", id, "finished job", j)
             results <- j * 2
         }
     }
     
     func main() {
     
         // In order to use our pool of workers we need to send
         // them work and collect their results. We make 2
         // channels for this.
         jobs := make(chan int, 100)
         results := make(chan int, 100)
     
         // This starts up 3 workers, initially blocked
         // because there are no jobs yet.
         for w := 1; w <= 3; w++ {
             go worker(w, jobs, results)
         }
     
         // Here we send 5 `jobs` and then `close` that
         // channel to indicate that's all the work we have.
         for j := 1; j <= 5; j++ {
             jobs <- j
         }
         close(jobs)
     
         // Finally we collect all the results of the work.
         //for a := 1; a <= 5; a++ {
         //   fmt.Println( <-results)
         //}
         for v := range results {
           fmt.Println(v)
         }
     }
    

      

    ——————————————————————————————————————————————————————————

    In this example we’ll look at how to implement a worker pool using goroutines and channels.

     
     
    package main
    
     
    import (
        "fmt"
        "time"
    )
    

    Here’s the worker, of which we’ll run several concurrent instances. These workers will receive work on the jobschannel and send the corresponding results on results. We’ll sleep a second per job to simulate an expensive task.

    func worker(id int, jobs <-chan int, results chan<- int) {
        for j := range jobs {
            fmt.Println("worker", id, "started  job", j)
            time.Sleep(time.Second)
            fmt.Println("worker", id, "finished job", j)
            results <- j * 2
        }
    }
    
     
    func main() {
    

    In order to use our pool of workers we need to send them work and collect their results. We make 2 channels for this.

        const numJobs = 5
        jobs := make(chan int, numJobs)
        results := make(chan int, numJobs)
    

    This starts up 3 workers, initially blocked because there are no jobs yet.

        for w := 1; w <= 3; w++ {
            go worker(w, jobs, results)
        }
    

    Here we send 5 jobs and then close that channel to indicate that’s all the work we have.

        for j := 1; j <= numJobs; j++ {
            jobs <- j
        }
        close(jobs)
    

    Finally we collect all the results of the work. This also ensures that the worker goroutines have finished. An alternative way to wait for multiple goroutines is to use a WaitGroup.

        for a := 1; a <= numJobs; a++ {
            <-results
        }
    }
    

    Our running program shows the 5 jobs being executed by various workers. The program only takes about 2 seconds despite doing about 5 seconds of total work because there are 3 workers operating concurrently.

  • 相关阅读:
    第十五章:Spring Boot 与 开发热部署
    第一章:(1)分布式基础理论
    第一章:(4)Dubbo 案例 HelloWorld
    第一章:(2)Dubbo核心概念
    第十四章:(3)Spring Boot 与 分布式 之 SpringCloud
    web安全测试AppScan扫描工具
    Cheatsheet: 2013 02.01 ~ 02.15
    Cheatsheet: 2013 04.17 ~ 04.30
    Cheatsheet: 2013 02.16 ~ 02.28
    Cheatsheet: 2013 01.21 ~ 01.31
  • 原文地址:https://www.cnblogs.com/oxspirt/p/13631529.html
Copyright © 2011-2022 走看看