我有两个goroutines独立产生数据,每个将它们发送到一个通道。在我的主要goroutine中,我想在输入这些输出时使用它们,但是不在乎它们的输入顺序。每个通道在耗尽其输出时都会自行关闭。虽然select语句是用于像这样独立使用输入的最佳语法,但是直到两个通道都关闭之前,我还没有看到一种简洁的循环方法。
for {
select {
case p, ok := <-mins:
if ok {
fmt.Println("Min:", p) //consume output
}
case p, ok := <-maxs:
if ok {
fmt.Println("Max:", p) //consume output
}
//default: //can't guarantee this won't happen while channels are open
// break //ideally I would leave the infinite loop
//only when both channels are done
}
}
我能想到的最好的方法是以下操作(只是草绘,可能会有编译错误):
for {
minDone, maxDone := false, false
select {
case p, ok := <-mins:
if ok {
fmt.Println("Min:", p) //consume output
} else {
minDone = true
}
case p, ok := <-maxs:
if ok {
fmt.Println("Max:", p) //consume output
} else {
maxDone = true
}
}
if (minDone && maxDone) {break}
}
但是,如果您使用的通道超过两个或三个,这看起来将变得站不住脚。我知道的唯一另一种方法是在switch语句中使用一个timout情况,该情况可能足够小以至于有可能提前退出,或者将太多的停机时间注入到最终循环中。有没有更好的方法来测试通道是否在select语句中?
那么,我该如何解决这个问题呢?零通道永远不会准备好进行通信。因此,每次遇到封闭频道时,您都可以将该频道设为零,以确保不再选择该频道。此处的可运行示例:http
://play.golang.org/p/8lkV_Hffyj
for {
select {
case x, ok := <-ch:
fmt.Println("ch1", x, ok)
if !ok {
ch = nil
}
case x, ok := <-ch2:
fmt.Println("ch2", x, ok)
if !ok {
ch2 = nil
}
}
if ch == nil && ch2 == nil {
break
}
}
至于担心它变得笨拙,我认为它不会。很少有频道一次转到太多地方的情况很少。这很少出现,我的第一个建议就是解决这个问题。较长的if语句将10个通道与nil进行比较,并不是试图在一个选择中处理10个通道的最糟糕的部分。
关闭通道的意思是该通道将不再允许写入数据。这个方法可以让通道数据的接受端知道数据已经全部发送完成了。 package main import "fmt" // 在这个例子中,我们使用通道jobs在main函数所在的协程和一个数据 // 接收端所在的协程通信。当我们数据发送完成后,我们关闭jobs通道 func main() { jobs := make(chan int, 5) d
问题内容: 我正在玩Golang,我创建了这个小应用程序,使用goroutines进行了多个并发的api调用。 当应用程序运行时,调用完成后,该应用程序将卡住,这是有道理的,因为由于通道未关闭,无法退出 范围c 循环。 我不确定在哪种情况下可以更好地关闭该通道。 问题答案: 当没有更多值要发送时,您将关闭通道,因此在这种情况下,所有goroutine已完成。 (请注意,from 仅将反映连接和协议
问题内容: 我在这里想要做的是使用键盘中断退出程序中所有正在进行的线程。这是创建线程的代码的精简版本: 程序本身要复杂得多,需要考虑大量影响线程的不同变量,甚至可以选择以顺序模式启动,在这种模式下,任务没有线程化,而是逐个启动,因此可能存在一些问题有了这个小的变化,我就想到了。我这样做的方式产生了50/50的结果。中断将起作用,但是线程将永远不会干净退出。有时他们会继续前进,但停止执行将来的线程,
问题内容: 刚尝试去最近。我想知道如果您有一条select语句等待在几个通道上进行通信,并且如果消息同时在两个或多个通道上出现,将会发生什么情况。如果所有消息都同时发出,那么select将如何确定接受哪个通道? 谢谢! 问题答案: 从规格: 如果可能发生多种情况,则将做出统一的伪随机选择,以决定执行哪个单一通信。 因此,选择是不确定的。
现在,您可以创建多个Youtube频道。在我的Android应用程序中,我需要让用户选择其中一个频道并使用它(获取订阅视频等)。 我想效仿官方YouTube应用程序,您可以在其中选择我在YouTube帐户中创建的频道之一。 编辑: 最后,我用易卜拉欣的建议解决了这个问题。在webview中,我使用了oAuth2身份验证,如下所示: https://accounts.google.com/o/oau
Go的select关键字可以让你同时等待多个通道操作,将协程(goroutine),通道(channel)和select结合起来构成了Go的一个强大特性。 package main import "time" import "fmt" func main() { // 本例中,我们从两个通道中选择 c1 := make(chan string) c2 := make(cha