是否可以在输入顺序中收集goroutine结果?

时间:2017-05-05 06:55:37

标签: go goroutine

我认为我的结果顺序应该与输入相同,是否可以进行常规操作?

我这样实现:

package main

import "fmt"
import "time"

func worker(id int, jobs <-chan int, results chan<- int) {
  for j := range jobs {
    time.Sleep(time.Second)
    results <- j * 2
  }
}

func main() {
  jobs := make(chan int, 100)
  results := make(chan int, 100)

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

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

  // Finally we collect all the results of the work.
  // But somehow I want to keep the order
  for a := 1; a <= 5; a++ {
    fmt.Println(<-results) // actually, I want to make it 2, 4, 6, 8, 10
  }
}

运行它here

1 个答案:

答案 0 :(得分:-2)

必须在worker func处保留结果顺序。 goroutine没有命令。设定结果必须保持秩序。

package main

import "fmt"
import "time"
import "sync/atomic"

var pivot uint32 = 1

func worker(id int, jobs <-chan int, results chan<- int) {
    for j := range jobs {
        time.Sleep(time.Second)

        for {
            if n := atomic.LoadUint32(&pivot); int(n) == j {
                results <- j * 2
                atomic.AddUint32(&pivot, 1)
                break
            }
            time.Sleep(time.Millisecond)
        }
    }
}

func main() {
    jobs := make(chan int, 100)
    results := make(chan int, 100)

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

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

    // Finally we collect all the results of the work.
    // But somehow I want to keep the order
    for a := 1; a <= 5; a++ {
        fmt.Println(<-results) // actually, I want to make it 2, 4, 6, 8, 10
    }
}

运行它here