我正在研究 Go 的一些并发模式。我查看了使用 goroutine 和输入/输出通道来实现后台工作者,并注意到当我将新作业发送到接收通道(基本上是将新作业排队)时,我必须在 goroutine 中执行它,否则调度会被搞砸。意义:
这会崩溃:
for _, jobData := range(dataSet) {
input <- jobData
}
这有效:
go func() {
for _, jobData := range(dataSet) {
input <- jobData
}
}()
对于更具体的事情,我玩了一些无意义的代码(这里是在 go playground 中):
package main
import (
"log"
"runtime"
)
func doWork(data int) (result int) {
// ... some 'heavy' computation
result = data * data
return
}
// do the processing of the input and return
// results on the output channel
func Worker(input, output chan int) {
for data := range input {
output <- doWork(data)
}
}
func ScheduleWorkers() {
input, output := make(chan int), make(chan int)
for i := 0 ; i < runtime.NumCPU() ; i++ {
go Worker(input, output)
}
numJobs := 20
// THIS DOESN'T WORK
// and crashes the program
/*
for i := 0 ; i < numJobs ; i++ {
input <- i
}
*/
// THIS DOES
go func() {
for i := 0 ; i < numJobs ; i++ {
input <- i
}
}()
results := []int{}
for i := 0 ; i < numJobs ; i++ {
// read off results
result := <-output
results = append(results, result)
// do stuff...
}
log.Printf("Result: %#v\n", results)
}
func main() {
ScheduleWorkers()
}
我正在努力解决这个微妙的差异 - 感谢您的帮助。谢谢。
智慧大石
有只小跳蛙
相关分类