Select Golang通道在选择中未接收

Select Golang通道在选择中未接收,select,go,channel,Select,Go,Channel,我目前正在编写一个小脚本,在其中我使用通道、选择和goroutine,我真的不明白为什么它不能像我想的那样运行 我有两个频道,我所有的goroutines都听 我将通道传递给每个goroutine,其中有一个select,必须根据数据首先出现的位置在2个goroutine之间进行选择 问题是没有一个goroutine属于第二种情况。我可以一个接一个地得到100份工作,我在日志中看到了一切。它很好地完成了第一个案例中的请求,之后它在第二个通道中发送了工作(如果它做得好,仍然是…),我没有更多的日志

我目前正在编写一个小脚本,在其中我使用通道、选择和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;iw、 在中,我认为您的解决方案可能有点过于复杂。这是一个简化的版本。请记住有许多实现。这是一篇很好的文章

或者更好的是直接从手册开始

(我想这可能就是你的目标)

无论如何,下面是一个不同类型的例子。有几种方法可以解决这个问题

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;iw、 因为你的函数是“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的例子你的嵌套选择可能不像你想象的那样工作;内部选择只执行一次,所以例如,
这是一个完全相关的评论,但不是问题的答案。这是一个完全相关的评论,但不是问题的答案。