英文:
Concurrent execution but serialized output
问题
我需要使用名为g1
、g2
、g3
的3个goroutine,并以轮询的方式在这3个goroutine之间分配1-10的数字。它们将根据提供的数字执行一些假设的工作。程序应以以下方式打印输出。
g1-1<br/>
g2-2<br/>
g3-3<br/>
g1-4<br/>
g2-5<br/>
g3-6<br/>
...
任务必须并发执行,但输出必须按顺序进行。
我已经实现了下面的代码来分配数字并打印输出,但输出的打印顺序不如上述所述。
我需要一些帮助来修复下面的代码,或者对实现上述所需输出的其他方法提出建议。
方法1:
package main
import (
"fmt"
"sync"
)
func main() {
chang1 := make(chan int)
chang2 := make(chan int)
chang3 := make(chan int)
var wg sync.WaitGroup
wg.Add(3)
go func() {
for num := range chang1 {
fmt.Println("g1", num)
}
wg.Done()
}()
go func() {
for num := range chang2 {
fmt.Println("g2", num)
}
wg.Done()
}()
go func() {
for num := range chang3 {
fmt.Println("g3", num)
}
wg.Done()
}()
channels := []chan int{chang1, chang2, chang3}
for i := 1; i <= 10; i++ {
currentCh := (i - 1) % 3
channels[currentCh] <- i
}
close(chang1)
close(chang2)
close(chang3)
wg.Wait()
}
输出(顺序不正确)
g1- 1<br>
g1- 4<br>
g2- 2<br>
g3- 3<br>
g1- 7<br>
g2- 5<br>
g2- 8<br>
g3- 6<br>
g3- 9<br>
g1- 10<br>
...
英文:
I need to use 3 goroutines named g1
, g2
, g3
. and distribute numbers from 1-10 among the above 3 goroutines in a round-robin fashion. They will do some hypothetical work based on the provided number. And program should print output in the following manner.
g1-1<br/>
g2-2<br/>
g3-3<br/>
g1-4<br/>
g2-5<br/>
g3-6<br/>
...
Tasks must be performed concurrently but the output must be in sequential order.
I have implemented the below code which distributes numbers and prints but output print order is not guaranteed as mentioned above.
I need some help to fix the below code or suggestions on another approach to get the above-desired output.
Approach 1:
package main
import (
"fmt"
"sync"
)
func main() {
chang1 := make(chan int)
chang2 := make(chan int)
chang3 := make(chan int)
var wg sync.WaitGroup
wg.Add(3)
go func() {
for num := range chang1 {
fmt.Println("g1", num)
}
wg.Done()
}()
go func() {
for num := range chang2 {
fmt.Println("g2", num)
}
wg.Done()
}()
go func() {
for num := range chang3 {
fmt.Println("g3", num)
}
wg.Done()
}()
channels := []chan int{chang1, chang2, chang3}
for i := 1; i <= 10; i++ {
currentCh := (i - 1) % 3
channels[currentCh] <- i
}
close(chang1)
close(chang2)
close(chang3)
wg.Wait()
}
output (with incorrect sequence)
g1- 1<br>
g1- 4<br>
g2- 2<br>
g3- 3<br>
g1- 7<br>
g2- 5<br>
g2- 8<br>
g3- 6<br>
g3- 9<br>
g1- 10<br>
...
答案1
得分: 2
如果你不想使用切片,我认为像这样的代码可以工作:- (playground)
package main
import (
"fmt"
)
func main() {
chang1 := make(chan string)
chang2 := make(chan string)
chang3 := make(chan string)
channels := []chan string{chang1, chang2, chang3}
for i := 1; i < 10; i += 3 {
go g1(i, channels[i%3])
go g2(i+1, channels[(i+1)%3])
go g3(i+2, channels[(i+2)%3])
fmt.Print(<-channels[i%3])
fmt.Print(<-channels[(i+1)%3])
fmt.Print(<-channels[(i+2)%3])
}
}
func g1(i int, chanel chan string) {
chanel <- fmt.Sprintln("g1", i)
}
func g2(i int, chanel chan string) {
chanel <- fmt.Sprintln("g2", i)
}
func g3(i int, chanel chan string) {
chanel <- fmt.Sprintln("g3", i)
}
输出结果:
g1 1
g2 2
g3 3
g1 4
g2 5
g3 6
g1 7
g2 8
g3 9
但请记住,在这个解决方案中,你需要运行3个 goroutine,然后等待它们全部给出结果,然后再继续执行。
如果这对你来说不可行,你需要使用带缓冲的通道。
英文:
if you don't want to use slice then I think something like this will work:- (playground)
package main
import (
"fmt"
)
func main() {
chang1 := make(chan string)
chang2 := make(chan string)
chang3 := make(chan string)
channels := []chan string{chang1, chang2, chang3}
for i := 1; i < 10; i += 3 {
go g1(i, channels[i%3])
go g2(i+1, channels[(i+1)%3])
go g3(i+2, channels[(i+2)%3])
fmt.Print(<-channels[i%3])
fmt.Print(<-channels[(i+1)%3])
fmt.Print(<-channels[(i+2)%3])
}
}
func g1(i int, chanel chan string) {
chanel <- fmt.Sprintln("g1", i)
}
func g2(i int, chanel chan string) {
chanel <- fmt.Sprintln("g2", i)
}
func g3(i int, chanel chan string) {
chanel <- fmt.Sprintln("g3", i)
}
output
g1 1
g2 2
g3 3
g1 4
g2 5
g3 6
g1 7
g2 8
g3 9
but keep in mind in this solution you have to run 3 goroutines then wait for all of them to give the result then go back
if this is not ok for you you need to use bufferd channels.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论