相当于 Java 中的 Go 通道
我有一个要求,我需要从一组阻塞队列中读取。阻塞队列由我正在使用的库创建。我的代码必须从队列中读取。我不想为每个阻塞队列创建一个读取器线程。相反,我想使用单个线程(或者可能最多使用2/3线程)轮询它们以获取数据的可用性。由于某些阻塞队列可能长时间没有数据,而其中一些队列可能会获得突发数据。以较小的超时轮询队列将起作用,但这根本不有效,因为它仍然需要继续循环所有队列,即使其中一些队列长时间没有数据。基本上,我正在寻找一种选择/epoll(用于套接字)的阻塞队列机制。任何线索都是值得赞赏的。
不过,在Go中做到这一点非常容易。下面的代码模拟了通道和 goroutines 的相同情况:
package main
import "fmt"
import "time"
import "math/rand"
func sendMessage(sc chan string) {
var i int
for {
i = rand.Intn(10)
for ; i >= 0 ; i-- {
sc <- fmt.Sprintf("Order number %d",rand.Intn(100))
}
i = 1000 + rand.Intn(32000);
time.Sleep(time.Duration(i) * time.Millisecond)
}
}
func sendNum(c chan int) {
var i int
for {
i = rand.Intn(16);
for ; i >= 0; i-- {
time.Sleep(20 * time.Millisecond)
c <- rand.Intn(65534)
}
i = 1000 + rand.Intn(24000);
time.Sleep(time.Duration(i) * time.Millisecond)
}
}
func main() {
msgchan := make(chan string, 32)
numchan := make(chan int, 32)
i := 0
for ; i < 8 ; i++ {
go sendNum(numchan)
go sendMessage(msgchan)
}
for {
select {
case msg := <- msgchan:
fmt.Printf("Worked on %s\n", msg)
case x := <- numchan:
fmt.Printf("I got %d \n", x)
}
}
}