注意-Go中的新手。
我编写了一个多路复用器,该多路复用器 应将 一组通道的输出合并为一个。对建设性的批评感到满意。
func Mux(channels []chan big.Int) chan big.Int {
// Count down as each channel closes. When hits zero - close ch.
n := len(channels)
// The channel to output to.
ch := make(chan big.Int, n)
// Make one go per channel.
for _, c := range channels {
go func() {
// Pump it.
for x := range c {
ch <- x
}
// It closed.
n -= 1
// Close output if all closed now.
if n == 0 {
close(ch)
}
}()
}
return ch
}
我正在测试:
func fromTo(f, t int) chan big.Int {
ch := make(chan big.Int)
go func() {
for i := f; i < t; i++ {
fmt.Println("Feed:", i)
ch <- *big.NewInt(int64(i))
}
close(ch)
}()
return ch
}
func testMux() {
r := make([]chan big.Int, 10)
for i := 0; i < 10; i++ {
r[i] = fromTo(i*10, i*10+10)
}
all := Mux(r)
// Roll them out.
for l := range all {
fmt.Println(l)
}
}
但是我的输出很奇怪:
Feed: 0
Feed: 10
Feed: 20
Feed: 30
Feed: 40
Feed: 50
Feed: 60
Feed: 70
Feed: 80
Feed: 90
Feed: 91
Feed: 92
Feed: 93
Feed: 94
Feed: 95
Feed: 96
Feed: 97
Feed: 98
Feed: 99
{false [90]}
{false [91]}
{false [92]}
{false [93]}
{false [94]}
{false [95]}
{false [96]}
{false [97]}
{false [98]}
{false [99]}
所以对我的问题:
我需要所有输入通道具有与输出通道相同的权限-即,我不能从一个通道获得所有输出,而从下一个通道获得所有输出,等等。
对于任何有兴趣的人-这是修复之后的最终代码,并且正确地(大概)使用了 sync.WaitGroup
import (
"math/big"
"sync"
)
/*
Multiplex a number of channels into one.
*/
func Mux(channels []chan big.Int) chan big.Int {
// Count down as each channel closes. When hits zero - close ch.
var wg sync.WaitGroup
wg.Add(len(channels))
// The channel to output to.
ch := make(chan big.Int, len(channels))
// Make one go per channel.
for _, c := range channels {
go func(c <-chan big.Int) {
// Pump it.
for x := range c {
ch <- x
}
// It closed.
wg.Done()
}(c)
}
// Close the channel when the pumping is finished.
go func() {
// Wait for everyone to be done.
wg.Wait()
// Close.
close(ch)
}()
return ch
}
从中产生的每个goroutine Mux
最终都从同一通道中拉出,因为c
在循环的每次迭代中都会进行更新-
它们不仅仅捕获的值c
。如果将通道传递给goroutine,您将获得预期的结果,如下所示:
for _, c := range channels {
go func(c <-chan big.Int) {
...
}(c)
}
您可以在此处测试此修改。
另一个可能的问题是您对n
变量的处理:如果使用进行运行GOMAXPROCS != 1
,则可能有两个goroutines试图一次对其进行更新。该sync.WaitGroup
类型将是等待goroutine完成的更安全的方法。
管道和多路复用器 延迟情况是难以忍受的。现代计算机能以惊人的速度生成数据,并且高速互联网(经常是在重要的服务器之间有多个并行连接)提供了极大的带宽,但是这可恶的延迟意味着电脑花了大量时间等待数据。基于延续的编程变得越来越流行的几个原因之一。让我们考虑一些规则的程序代码: string a = db.StringGet("a"); string b = db.StringGet("b"); 按照这
当用户单击单击区域时,我试图传递所选帐户的ID。 然而,在我的帐户组件中,这将使我们: 我越来越不确定了。 有没有办法使用链接将道具传递到我的组件?
默认的,当连接道不同的命名空间后一个单一的链接将会被使用。 const socket = io(); const adminSocket = io('/admin'); // a single connection will be established 注意:重用相同的命名空间将会创建两个连接: const socket = io(); const socket2 = io(); // wil
前面两节里我们用到的输入和输出都是二维数组,但真实数据的维度经常更高。例如,彩色图像在高和宽2个维度外还有RGB(红、绿、蓝)3个颜色通道。假设彩色图像的高和宽分别是$h$和$w$(像素),那么它可以表示为一个$3\times h\times w$的多维数组。我们将大小为3的这一维称为通道(channel)维。本节我们将介绍含多个输入通道或多个输出通道的卷积核。 多输入通道 当输入数据含多个通道时
这是我试图解决的编程问题:2520是最小的数字,可以被1到10的每个数字除,没有任何余数。 可以被1到20的所有数字整除的最小正数是多少? 这是到目前为止我的解决方案,但是每次答案都是零,所以我认为我的代码中有一个错误。任何帮助都将不胜感激。
主要内容:同步/异步/阻塞/非阻塞,BIO,NIO,IO multiplexing,select,poll,epollRedis利用epoll实现io多路复用,将连接信息和事件放入队列,一次放到文件事件派发器,事件派发器将事件分发给事件处理器。 io多路复用机制:监视多个描述符fd,一旦某个描述符就绪,可以通知程序进行响应的读写操作。这种机制需要select,poll,epoll。多个连接公用一个阻塞对象,应用程序只需要在一个阻塞对象上等待,不需要全部的阻塞连接。当某条连接有新的数据可以处理的时