Golang频道选择不接收

时间:2017-10-04 14:22:07

标签: select go channel

我目前正在编写一个小脚本,我使用频道,选择和goroutine,我真的不明白为什么它不像我想的那样运行。

我有两个频道,我的所有goroutines都听。

我将通道传递给每个goroutine,其中有一个选择,必须在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个工人:3个工作在通道IN,直接3个工人接受它们,如果3个工作验证条件,它们在通道OUT中发送。直接由2名工人接管他们,第3份工作由前3名工人中的一名接收......

现在我希望您对我的第一个代码有更好的理解。但在我的代码中,我从未接受过第二种情况。

3 个答案:

答案 0 :(得分:1)

您的quitInquitOut频道基本上没用:您创建它们并尝试从它们接收。由于没有人知道他们的存在,所以你无法写信给这些频道。我不能多说,因为我不明白代码应该做什么。

答案 1 :(得分:1)

我认为您的解决方案可能有点过于复杂。这是一个简化版本。请记住,有许多实现。一篇好文章

https://medium.com/smsjunk/handling-1-million-requests-per-minute-with-golang-f70ac505fcaa

甚至可以从Go手册中获得更好的

https://gobyexample.com/worker-pools(我认为这可能是你的目标)

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

<script type="text/javascript">

$(document).ready(function () {

    function PageController()
    {
        var that = this,
            dictionary = {
                elements: { btnAppend: null, bladeContainer: null },
                selectors: { btnAppend: '#btnAppend', bladeContainer: '.blade-container', tmplBlade: '#tmplBlade' }
            };

        var initialize = function () {

            // Elements
            dictionary.elements.btnAppend = $(dictionary.selectors.btnAppend);
            dictionary.elements.bladeContainer = $(dictionary.selectors.bladeContainer);

            // Events
            dictionary.elements.btnAppend.on('click', that.on.click.btnAppend);
        };

        this.on = {
            click: {
                btnAppend: function (e) {
                    var html = $(dictionary.selectors.tmplBlade).html().trim();
                    var $element = $(html);

                    $element.hide();
                    dictionary.elements.bladeContainer.prepend($element);

                    // Slide-in
                    $element.show('slide', { direction: 'left' });
                }
            }
        };

        initialize();
    }

    var pageController = new PageController();
});

</script>

答案 2 :(得分:0)

因为您的功能是“工作”,而您正在调用“工作”。