如何使用奇数和偶数线程打印 N 个整数

我正在尝试从2个go例程打印N个数字:


去例行奇数():这只能打印奇数


去例行偶():这只能打印偶数


输出应为:1 2 3 4 5 6 7 8 9 10


我正在尝试使用同步来解决此问题。等待组。我有以下疑问:


问题 1.哪种并发机制最适合此问题?通道、等待组、互斥锁等?如果您可以为相同的代码提供工作代码,那将是理想的。


问题 2.为什么我无法通过以下代码正确打印序列?我做错了一些我无法纠正的事情。请帮助纠正。


package main


import (

    "fmt"

    "sync"

)


var wg sync.WaitGroup

var wgO sync.WaitGroup

var wgE sync.WaitGroup


func even() {

    defer wg.Done()


    for i := 2; i <= 10; i += 2 {

        wgE.Add(1)

        wgO.Wait()

        fmt.Println(i)

        wgE.Done()

    }

}

func odd() {

    defer wg.Done()


    for i := 1; i <= 10; i += 2 {

        wgO.Add(1)

        fmt.Println(i)

        wgO.Done()

        wgE.Wait()

    }

}

func main() {

    wg.Add(2)

    go even()

    go odd()

    wg.Wait()

}


PIPIONE
浏览 78回答 2
2回答

莫回无

问题 1.哪种并发机制最适合此问题?通道、等待组、互斥锁等?没有。您的问题与要并发执行的操作相反,并且没有并发机制可以帮助您。问题 2.为什么我无法通过以下代码正确打印序列?您希望独立戈鲁丁同步运行。因此,您必须中断并发性。从技术上讲,在这两个戈鲁丁之间基于通道的乒乓球是可行的,实际上使它们不连贯。您的问题没有合理的“并发”解决方案,您不会从严重解决方案中学到一些东西,其中并发性被强行破坏。

潇潇雨雨

问1:Which concurrency mechanism best suited for this problem?答案 1:无。打印连续数字的问题不是并发的。因此,即使您实现了使用Go的并发机制(使用通道或互斥锁)的解决方案,它也不会/无法实际并发运行,因为您想要的是按顺序打印数字。同时运行将打印数字是一个非确定性的顺序。问2:Why I am not able to print the sequence correctly through below code?A2:您的代码打印无序,因为一旦触发了 go 例程,您就无法知道它们的执行顺序。所以代码:...go even()go odd()...甚至不能保证函数内部的循环会在函数内部的循环之前启动,即使函数在调用之前也是如此。evenoddevenA2.1:您的代码有时会崩溃,因为在函数内部调用之前,内部函数可能会被调用。WaitGroup is reused before previous Wait has returnedwgO.Done()oddwgO.Wait()even下面是一个非常愚蠢的实现,使用它可以工作,并说明问题的解决方案必须打破并发才能工作。为了按顺序打印数字,我必须等待每个go例程的完成......sync.WaitGroupfunc main() {&nbsp; &nbsp; var wg sync.WaitGroup&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; for i := 0; i <= 10; i++ {&nbsp; &nbsp; &nbsp; &nbsp; if i%2 == 0 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; go func(i int) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; defer wg.Done()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(i)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }(i)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wg.Wait()&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; go func(i int) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; defer wg.Done()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(i)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }(i)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wg.Wait()&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}我不会太纠结于这个问题,因为它不是倾向于Go的并发机制的好例子。这里有一门关于cooursera的很棒的课程,可以学习Go的并发性
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go