【发布时间】:2018-03-15 23:48:50
【问题描述】:
我目前正在编写一个使用通道、选择和 goroutine 的小脚本,但我真的不明白为什么它没有像我想的那样运行。
我有 2 个频道供我所有的 goroutine 收听。
我将通道传递给每个 goroutine,其中有一个 select,必须根据数据首先出现的位置在 2 个之间进行选择。
问题是没有goroutine属于第二种情况。我可以一个接一个地收到 100 个工作,我在日志中看到了所有内容。它在第一种情况下的要求很好,之后它在第二个频道中发送了工作(如果它做得很好......)我没有更多的日志了。 我只是不明白为什么......
如果有人可以启发我:)
package main
func main() {
wg := new(sync.WaitGroup)
in := make(chan *Job)
out := make(chan *Job)
results := make(chan *Job)
for i := 0; i < 50; i++ {
go work(wg, in, out, results)
}
wg.Wait()
// Finally we collect all the results of the work.
for elem := range results {
fmt.Println(elem)
}
}
func Work(wg *sync.WaitGroup, in chan *Job, out chan *Job, results chan *Job) {
wg.Add(1)
defer wg.Done()
for {
select {
case job := <-in:
ticker := time.Tick(10 * time.Second)
select {
case <-ticker:
// DO stuff
if condition is true {
out <- job
}
case <-time.After(5 * time.Minute):
fmt.Println("Timeout")
}
case job := <-out:
ticker := time.Tick(1 * time.Minute)
select {
case <-ticker:
// DO stuff
if condition is true {
results <- job
}
case <-quitOut:
fmt.Println("Job completed")
}
}
}
}
我创建了一些工人,他们听 2 个频道并将最终结果发送到第 3 个。
它对接收到的作业做一些事情,如果它验证给定的条件,它会将这个作业传递到下一个通道,如果它验证一个条件,它会将作业传递到结果通道。
所以,在我的脑海中,我有一个这样的管道,用于 5 个工作人员,例如:通道 IN 中的 3 个工作,直接 3 个工作人员接受它们,如果 3 个工作验证条件,它们将在通道 OUT 中发送。直接由 2 名工人接手,第 3 份工作由前 3 名工人中的一名接手……
现在我希望您对我的第一个代码有更好的理解。但在我的代码中,我从来没有遇到过第二种情况。
【问题讨论】:
-
Job 类型的定义在哪里?此外,您的工作定义不应该在 goroutine 中。您正在启动多个侦听器。
-
Job 是在另一个 go 文件中定义的,我没有把他的,因为他包含很多信息......你的意思是我的工作定义不应该在 goroutine 中?跨度>
-
@JimB 我的拼写错误我有一个 channeliIn 的案例和一个 channel out 的案例
-
您的嵌套选择可能不像您认为的那样工作;内部选择只会执行一次,所以没有办法例如
<-ticker案例发送到quitIn并在<-quitIn案例中执行;不可能。只有一个案件将被执行。quitOut也一样。