Select Golang通道在选择中未接收
我目前正在编写一个小脚本,在其中我使用通道、选择和goroutine,我真的不明白为什么它不能像我想的那样运行 我有两个频道,我所有的goroutines都听 我将通道传递给每个goroutine,其中有一个select,必须根据数据首先出现的位置在2个goroutine之间进行选择 问题是没有一个goroutine属于第二种情况。我可以一个接一个地得到100份工作,我在日志中看到了一切。它很好地完成了第一个案例中的请求,之后它在第二个通道中发送了工作(如果它做得好,仍然是…),我没有更多的日志。 我只是不明白为什么 如果有人能启发我:)Select Golang通道在选择中未接收,select,go,channel,Select,Go,Channel,我目前正在编写一个小脚本,在其中我使用通道、选择和goroutine,我真的不明白为什么它不能像我想的那样运行 我有两个频道,我所有的goroutines都听 我将通道传递给每个goroutine,其中有一个select,必须根据数据首先出现的位置在2个goroutine之间进行选择 问题是没有一个goroutine属于第二种情况。我可以一个接一个地得到100份工作,我在日志中看到了一切。它很好地完成了第一个案例中的请求,之后它在第二个通道中发送了工作(如果它做得好,仍然是…),我没有更多的日志
主程序包
func main(){
wg:=新建(sync.WaitGroup)
in:=制造(成龙*工作)
out:=制造(成龙*工作)
结果:=制造(成龙*工作)
对于i:=0;i<50;i++{
开始工作(工作组、输入、输出、结果)
}
wg.Wait()
//最后我们收集了所有的工作结果。
对于元素:=范围结果{
fmt.Println(要素)
}
}
func工作(wg*sync.WaitGroup、in-chan*工作、out-chan*工作、results chan*工作){
工作组.添加(1)
推迟工作组完成()
为了{
挑选{
案例作业:=你的退出
和退出
频道基本上是无用的:你创建它们并尝试从它们那里接收。你不能这样做,因为没有人可以向这些频道写信,因为没有人知道它们的存在。我不能多说,因为我不明白代码应该做什么。你的退出
和退出
频道基本上是无用的:你创建它们并尝试从它们那里接收。你不能这样做,因为没有人可以向这些频道写信,因为没有人知道它们的存在。我不能多说,因为我不明白这些代码应该做什么。我认为你的解决方案可能有点过于复杂这是一个简化的版本。请记住有很多实现。这是一篇好文章
或者更好的是直接从手册开始
(我想这可能就是你的目标)
无论如何,下面是一个不同类型的例子。有几种方法可以解决这个问题
package main
import (
"context"
"log"
"os"
"sync"
"time"
)
type worker struct {
wg *sync.WaitGroup
in chan job
quit context.Context
}
type job struct {
message int
}
func main() {
numberOfJobs := 50
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
w := worker{
wg: &sync.WaitGroup{},
in: make(chan job),
quit: ctx,
}
for i := 0; i < numberOfJobs; i++ {
go func(i int) {
w.in <- job{message: i}
}(i)
}
counter := 0
for {
select {
case j := <-w.in:
counter++
log.Printf("Received job %+v\n", j)
// DO SOMETHING WITH THE RECEIVED JOB
// WORKING ON IT
x := j.message * j.message
log.Printf("job processed, result %d", x)
case <-w.quit.Done():
log.Printf("Recieved quit, timeout reached. Number of jobs queued: %d, Number of jobs complete: %d\n", numberOfJobs, counter)
os.Exit(0)
default:
// TODO
}
}
}
主程序包
进口(
“上下文”
“日志”
“操作系统”
“同步”
“时间”
)
类型工作结构{
wg*sync.WaitGroup
成龙工作
退出上下文
}
类型作业结构{
消息整型
}
func main(){
工作数量:=50
ctx,cancel:=context.WithTimeout(context.Background(),3*time.Second)
推迟取消
w:=工人{
wg:&sync.WaitGroup{},
in:make(chan job),
退出:ctx,
}
对于i:=0;i w、 在中,我认为您的解决方案可能有点过于复杂。这是一个简化的版本。请记住有许多实现。这是一篇很好的文章
或者更好的是直接从手册开始
(我想这可能就是你的目标)
无论如何,下面是一个不同类型的例子。有几种方法可以解决这个问题
package main
import (
"context"
"log"
"os"
"sync"
"time"
)
type worker struct {
wg *sync.WaitGroup
in chan job
quit context.Context
}
type job struct {
message int
}
func main() {
numberOfJobs := 50
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
w := worker{
wg: &sync.WaitGroup{},
in: make(chan job),
quit: ctx,
}
for i := 0; i < numberOfJobs; i++ {
go func(i int) {
w.in <- job{message: i}
}(i)
}
counter := 0
for {
select {
case j := <-w.in:
counter++
log.Printf("Received job %+v\n", j)
// DO SOMETHING WITH THE RECEIVED JOB
// WORKING ON IT
x := j.message * j.message
log.Printf("job processed, result %d", x)
case <-w.quit.Done():
log.Printf("Recieved quit, timeout reached. Number of jobs queued: %d, Number of jobs complete: %d\n", numberOfJobs, counter)
os.Exit(0)
default:
// TODO
}
}
}
主程序包
进口(
“上下文”
“日志”
“操作系统”
“同步”
“时间”
)
类型工作结构{
wg*sync.WaitGroup
成龙工作
退出上下文
}
类型作业结构{
消息整型
}
func main(){
工作数量:=50
ctx,cancel:=context.WithTimeout(context.Background(),3*time.Second)
推迟取消
w:=工人{
wg:&sync.WaitGroup{},
in:make(chan job),
退出:ctx,
}
对于i:=0;i w、 因为你的函数是“Work”,你调用的是“Work”。因为你的函数是“Work”,你调用的是“Work”.你对类型作业的定义在哪里?你的工作定义也不应该出现在一个goroutine中。你正在旋转多个侦听器。作业定义在另一个go文件中,我没有放在他的go文件中,因为他包含很多信息……你说我的工作定义不应该出现在goroutine中是什么意思?@JimB my bad a拼写错误我有一个案例对于channeliIn和channel out,嵌套的选择可能不会按您认为的方式工作;内部选择只执行一次,因此无法执行,例如,类型Job的定义在哪里?此外,您的工作定义不应位于这样的goroutine中。您正在旋转多个侦听器。Job是在另一个go文件我没有放在他那里,因为他包含了很多信息……你说我的工作定义不应该在goroutine中是什么意思?@JimB my bad a拼写错误我有一个channeliIn和一个channel Out的例子你的嵌套选择可能不像你想象的那样工作;内部选择只执行一次,所以例如,这是一个完全相关的评论,但不是问题的答案。这是一个完全相关的评论,但不是问题的答案。