Go 通道就绪时,从多个通道选择所有值
我是刚来戈朗的,我面临着这个问题 我有几个频道 一些有效载荷在不同的时间到达该通道 如何在通道准备吐出时,从通道中逐个获取所有值 例如,我编写了以下代码: 包干管Go 通道就绪时,从多个通道选择所有值,go,Go,我是刚来戈朗的,我面临着这个问题 我有几个频道 一些有效载荷在不同的时间到达该通道 如何在通道准备吐出时,从通道中逐个获取所有值 例如,我编写了以下代码: 包干管 import ( "fmt" "time" "math/rand" ) func main() { arr1 := []int8{1,2,3,4,5} arr2 := []int8{6,7,8,9,10} c1 := make(chan int8) c2 := make(ch
import (
"fmt"
"time"
"math/rand"
)
func main() {
arr1 := []int8{1,2,3,4,5}
arr2 := []int8{6,7,8,9,10}
c1 := make(chan int8)
c2 := make(chan int8)
go func() {
for _, val := range arr1 {
time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
c1 <- val
}
}()
go func() {
for _, val := range arr2 {
time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
c2 <- val
}
}()
select {
case res1 := <- c1:
fmt.Println(res1)
case res2 := <- c2:
fmt.Println(res2)
}
fmt.Println("Hello, test")
}
但在这种情况下,我只从其中一个通道获得第一个值
请告诉我如何解决我的问题
链接到go play选择不等待go例程。要实现这一点,您应该将其封装在for语句中。这样,select将一直运行,直到其中一个案例返回并中断for语句
for {
select {
...
您还可以使用非阻塞和等待组的缓冲通道。像这样:
arr1 := []int8{1,2,3,4,5}
arr2 := []int8{6,7,8,9,10}
c1 := make(chan int8, len(arr1))
c2 := make(chan int8, len(arr2))
var wg sync.WaitGroup
wg.Add(1) // First wait group
go func() {
for _, val := range arr1 {
time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
c1 <- val
}
wg.Done()
}()
wg.Add(1) // Second wait group
go func() {
for _, val := range arr2 {
time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
c2 <- val
}
wg.Done()
}()
// executed after wg.Done() is called 2 times since we have 2 wait groups
wg.Wait()
// We are not writing to channels anymore so we can close them.
close(c1)
close(c2)
for value := range c1 {
fmt.Println(value)
}
for value := range c2 {
fmt.Println(value)
}
fmt.Println("Hello, test")
你必须做几件事 1确保完成源代码后关闭频道。 2在通道上迭代,直到关闭 例如:
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
arr1 := []int8{1, 2, 3, 4, 5}
arr2 := []int8{6, 7, 8, 9, 10}
c1 := make(chan int8)
c2 := make(chan int8)
go func() {
for _, val := range arr1 {
time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
c1 <- val
}
close(c1)
}()
go func() {
for _, val := range arr2 {
time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
c2 <- val
}
close(c2)
}()
_c1 := true
_c2 := true
var res1, res2 int8
for _c1 == true || _c2 == true {
select {
case res1, _c1 = <-c1:
if _c1 == true {
fmt.Println(res1)
}
case res2, _c2 = <-c2:
if _c2 == true {
fmt.Println(res2)
}
}
}
fmt.Println("Hello, test")
}
你不必使用两个频道。只需使用1个通道并将多个goroutine中的值存储到其中。通道是轻量级线程连接器,速度快,可以多次实例化以存储来自多个goroutine的值 您的代码的问题是,它没有从goroutines通道返回的循环到循环的值。使用“选择”仅打印一次。select使其他goroutine等待,直到它执行它所拥有的一种可能的情况。如果所有的情况都是可能的,那么它会随机选择执行 您仅从通道获得一个值的原因是,当goroutine工作时,它们会按顺序将值从数组存储到通道。当这种情况发生时,您可以在主线程中调用select语句,并使用案例从goroutine中的通道获取值。由于您不在通道上循环,因此您只能从通道中获得一个值,即它第一次接收到的值。在本例中,您将按顺序将数组循环到goroutines中的通道中,因此您将获得数组的第一个索引,因为它是将首先发送到主线程中select语句的值。您选择的所有案例都可以执行,因此它将随机执行其中一个案例,您将在其中一个数组中获得第一个索引 要解决这个问题,您需要在通道上循环以逐个获取存储在其中的值。此外,您还需要同步所有线程以避免死锁情况,这种情况发生在主线程不知道何时停止从goroutine调用通道时,因为它们是异步工作的。您的通道在goroutines中获得值并被调用到循环中的主线程之后,就准备好吐出该值。代码如下:
package main
import (
"fmt"
"time"
"math/rand"
"sync"
)
// writer set numbers from array to channel
func writer(ch chan int, arr []int ,wgwrite *sync.WaitGroup) {
defer wgwrite.Done()
for _, val := range arr {
time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
ch <- val
}
}
// reader receive input from writer channels and print them all
func reader(ch chan int, wgread *sync.WaitGroup) {
defer wgread.Done()
for i:= range ch {
fmt.Println(i)
}
fmt.Println("Hello, test")
}
func main() {
arr1 := []int{1,2,3,4,5}
arr2 := []int{6,7,8,9,10}
ch := make(chan int)
wgwrite := &sync.WaitGroup{}
wgread := &sync.WaitGroup{}
wgwrite.Add(2)
go writer(ch, arr1, wgwrite)
go writer(ch, arr2, wgwrite)
wgread.Add(1)
go reader(ch, wgread)
wgwrite.Wait()
close(ch)
wgread.Wait()
}
希望能有所帮助。一种方法是将频道合并为一个频道,并在其上覆盖范围。参见示例中的风扇
package main
import (
"fmt"
"time"
"math/rand"
"sync"
)
// writer set numbers from array to channel
func writer(ch chan int, arr []int ,wgwrite *sync.WaitGroup) {
defer wgwrite.Done()
for _, val := range arr {
time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
ch <- val
}
}
// reader receive input from writer channels and print them all
func reader(ch chan int, wgread *sync.WaitGroup) {
defer wgread.Done()
for i:= range ch {
fmt.Println(i)
}
fmt.Println("Hello, test")
}
func main() {
arr1 := []int{1,2,3,4,5}
arr2 := []int{6,7,8,9,10}
ch := make(chan int)
wgwrite := &sync.WaitGroup{}
wgread := &sync.WaitGroup{}
wgwrite.Add(2)
go writer(ch, arr1, wgwrite)
go writer(ch, arr2, wgwrite)
wgread.Add(1)
go reader(ch, wgread)
wgwrite.Wait()
close(ch)
wgread.Wait()
}