如何使用奇数和偶数线程打印 N 个整数
How to print N integers using odd and even thread
我正在尝试从 2 个 go 例程中打印 N 个数字:
go routine odd():这个只能打印奇数
go routine even():这个只能打印偶数
输出应该是: 1 2 3 4 5 6 7 8 9 10
我正在尝试使用 sync.WaitGroup 解决这个问题。我有以下疑问:
Q1。哪种并发机制最适合这个问题?通道、等待组、互斥量等?如果您能提供相同的工作代码,那将是理想的选择。
Q2。为什么我无法通过以下代码正确打印序列?我做错了我无法纠正的事情。请帮忙改正。
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()
}
Q1. Which concurrency mechanism best suited for this problem? channel, waitgroup, mutex, etc?
None。您的问题与要同时完成的事情相反,没有并发机制可以帮助您。
Q2. Why I am not able to print the sequence correctly through below code?
您希望独立的 goroutines 运行 同步。所以你必须打破并发。从技术上讲,这两个 goroutine 之间基于通道的乒乓球会起作用,实际上使它们不并发。你的问题没有合理的“并发”解决方案,你不会从并发性被强行破坏的残缺解决方案中学到东西。
Q1:Which concurrency mechanism best suited for this problem?
A1:None。您打印序号的问题不是并发的。因此,即使您实现了一个使用 Go 的并发机制(使用通道或互斥锁)的解决方案,它也不会 t/couldn 实际上 运行 并发,因为您想要的是 顺序 打印你的号码。 运行 同时打印数字是一个不确定的顺序。
Q2:Why I am not able to print the sequence correctly through below code?
A2: 你的代码打印顺序不对 因为一旦go例程被触发,你就无法知道它们的执行顺序。所以代码:
...
go even()
go odd()
...
甚至不能保证 even
函数内的循环将在 odd
函数内的循环之前开始,即使 even
函数在之前被调用。
A2.1:您的代码有时会出现混乱 WaitGroup is reused before previous Wait has returned
,因为 odd
函数中的 wgO.Done()
可能会在之前被调用wgO.Wait()
在 even
函数内部被调用。
以下是一个非常愚蠢 的实现,它使用 sync.WaitGroup
有效,并说明了您的问题的解决方案如何必须打破并发才能起作用。为了按顺序打印数字,我必须等待每个 go 例程的完成...
func main() {
var wg sync.WaitGroup
for i := 0; i <= 10; i++ {
if i%2 == 0 {
wg.Add(1)
go func(i int) {
defer wg.Done()
fmt.Println(i)
}(i)
wg.Wait()
} else {
wg.Add(1)
go func(i int) {
defer wg.Done()
fmt.Println(i)
}(i)
wg.Wait()
}
}
}
我不会太在意这个问题,因为它不是学习 Go 并发机制的好例子。
cooursera 上有很好的学习 Go 并发的课程here
我正在尝试从 2 个 go 例程中打印 N 个数字:
go routine odd():这个只能打印奇数
go routine even():这个只能打印偶数
输出应该是: 1 2 3 4 5 6 7 8 9 10
我正在尝试使用 sync.WaitGroup 解决这个问题。我有以下疑问:
Q1。哪种并发机制最适合这个问题?通道、等待组、互斥量等?如果您能提供相同的工作代码,那将是理想的选择。
Q2。为什么我无法通过以下代码正确打印序列?我做错了我无法纠正的事情。请帮忙改正。
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()
}
Q1. Which concurrency mechanism best suited for this problem? channel, waitgroup, mutex, etc?
None。您的问题与要同时完成的事情相反,没有并发机制可以帮助您。
Q2. Why I am not able to print the sequence correctly through below code?
您希望独立的 goroutines 运行 同步。所以你必须打破并发。从技术上讲,这两个 goroutine 之间基于通道的乒乓球会起作用,实际上使它们不并发。你的问题没有合理的“并发”解决方案,你不会从并发性被强行破坏的残缺解决方案中学到东西。
Q1:Which concurrency mechanism best suited for this problem?
A1:None。您打印序号的问题不是并发的。因此,即使您实现了一个使用 Go 的并发机制(使用通道或互斥锁)的解决方案,它也不会 t/couldn 实际上 运行 并发,因为您想要的是 顺序 打印你的号码。 运行 同时打印数字是一个不确定的顺序。
Q2:Why I am not able to print the sequence correctly through below code?
A2: 你的代码打印顺序不对 因为一旦go例程被触发,你就无法知道它们的执行顺序。所以代码:
...
go even()
go odd()
...
甚至不能保证 even
函数内的循环将在 odd
函数内的循环之前开始,即使 even
函数在之前被调用。
A2.1:您的代码有时会出现混乱 WaitGroup is reused before previous Wait has returned
,因为 odd
函数中的 wgO.Done()
可能会在之前被调用wgO.Wait()
在 even
函数内部被调用。
以下是一个非常愚蠢 的实现,它使用 sync.WaitGroup
有效,并说明了您的问题的解决方案如何必须打破并发才能起作用。为了按顺序打印数字,我必须等待每个 go 例程的完成...
func main() {
var wg sync.WaitGroup
for i := 0; i <= 10; i++ {
if i%2 == 0 {
wg.Add(1)
go func(i int) {
defer wg.Done()
fmt.Println(i)
}(i)
wg.Wait()
} else {
wg.Add(1)
go func(i int) {
defer wg.Done()
fmt.Println(i)
}(i)
wg.Wait()
}
}
}
我不会太在意这个问题,因为它不是学习 Go 并发机制的好例子。
cooursera 上有很好的学习 Go 并发的课程here